python執行緒和程序,生產者消費者模型

2021-07-08 10:29:01 字數 4447 閱讀 5671

應用程式像工廠,程序像車間,執行緒像工人

乙個程序中的執行緒可以在不同cpu上執行,乙個執行緒不能同時在兩個cpu上執行

python中有乙個全域性直譯器鎖(gil global interpreter lock),他就像一把鎖所在程序上,保證同一時刻,乙個程序中無論有多少執行緒,只能保證有乙個執行緒出來

隨著cpu核數的增加,python中可以建立多個程序,乙個程序中有乙個全域性直譯器,這樣乙個cpu跑乙個程序,乙個程序同一時刻只能出乙個執行緒,達到並行的目的

執行緒和程序的區別 :

執行緒是可以共享記憶體的,而程序不可以共享記憶體,乙個程序就像乙個應用程式,例如qq和**,這屬於兩個程序,在qq中發資訊肯定不會發到**中,但是在qq中存在很多的執行緒,他們可以共享記憶體,他們都屬於乙個程序,

假如eclipse在執行時佔中400m的記憶體空間,那麼這個程序下的執行緒的共享空間為這個主程序所占用的記憶體空間,就是eclipse的執行緒的記憶體共享就為400m

執行緒沒有辦法單獨執行,執行緒必須在程序中

多程序之間的通訊

多程序之間無法直接通訊,它必須借助乙個第三方的橋梁

1 佇列

from multiprocessing import process, queue 

deff

(q,n):

q.put([ n, 'hello'])

if __name__ == '__main__':

q = queue()

for i in range(5):

p = process(target=f, args=(q,i))

p.start()

print q.get()

執行緒的安全問題,假如現在有十個執行緒,同時修改乙個變數,讓這個變數+1,那麼會出現乙個問題,假如a執行緒正在修改變數,現在變數為m=2,a執行緒操作m,目的是讓a+1,然而a修改到一半的時候,執行緒b又進來了,執行緒b此時取的m的值也是2,a修改完了m=3,b修改完了m還是等於3 ,非常不安全

解決辦法,就是加一把鎖,形象的例子:

假如現在有10個人要上廁所,鑰匙在我手裡,這個時候a進來,他把門關上了,別人就進不去,只有等a完事後其他人才能進來,這個門就是控制線程的那把鎖

**實現就通過乙個lock來實現,lock 只允許乙個執行緒訪問

lock=threading.lock()

lock.acquire()

lock.release()

**如下

val=0

#全域性變數

defrun

(self,):

#lock.acquire()

time.sleep(1)

global val

lock.acquire()

val+=1

print

'%s' %val

lock.release() //這個地方執行完了必須relese,讓後面的執行緒繼續執行,否則後面無法執行

lock=threading.lock()

for i in range(100):

t=threading.thread(target=run,args=(i,))

t.start()

假如乙個廁所門裡有兩個坑,允許兩個人同時上廁所,即允許兩個執行緒同時修改變數,那麼用samp

samp = threading.boundedsemaphore(3)

samp.acquire()

samp.release()

當引數為1時,實際上就等於lock

val=0

#全域性變數

defrun

(self,):

#lock.acquire()

time.sleep(1)

global val

samp.acquire()

val+=1

print

'%s' %val

samp.release()

lock=threading.lock()

samp = threading.boundedsemaphore(3)

for i in range(100):

t=threading.thread(target=run,args=(i,))

t.start()

全域性變數和區域性變數

全域性變數是在方法之外定義的變數,方法內部不能修改全域性變數

例如 val=0 #全域性變數

def run(self,n)

val+=1

程式會報錯,方法內不能直接就該全域性變數

在假如 val=0 #全域性變數

def run(self,n)

val=1

print val

輸出結果會是1,這是為什麼呢,應為此時函式內部的val與全域性變數val並不是乙個,函式內部的 val是區域性變數,函式外部的val為全域性變數

假如 執行c=run(『haha』)

print val

會輸出 0

1假如要在函式內重新定義區域性變數

必須在函式中重新宣告全域性變數

val=0   #全域性變數

def run(self,n)

global

valval=1

print val

join() 執行到join時,例如執行到join(3)然後就在這個地方等待三秒,

from threading import thread

import time

class

mythread

(thread):

defrun

(self):

time .sleep(5)

print

'我是執行緒'

defbar

():print

'bar'

t1=mythread(target=bar )

t1.start()

t1.join(3)

print 『over'

生產者和消費者模型

比較好的**

採用面向類的生產者消費者模型

#_*_ coding:utf-8 _*_

from threading import thread

from queue import queue

import time

class

producer

(thread):

def__init__

(self,name,queue):

self.__name=name

self.__queue=queue

super(producer,self).__init__() #重寫了父類的方法

defrun

(self):

while

true:

if self.__queue.full():

time.sleep(1)

else :

self.__queue.put('baozi')

time.sleep(1)

print

'%s生產了乙個包子'%(self.__name)

class

consumer

(thread):

def__init__

(self,name,queue):

self.__name=name

self.__queue=queue

super(consumer,self).__init__()

defrun(self):

while

true:

if self.__queue.empty():

time.sleep(1)

else :

self.__queue.get()

time.sleep(1)

print

'%s 消費乙個包子'%(self.__name,)

que =queue(maxsize=100)

baozi_make1=producer('mahzongyi',que)

baozi_make1.start()

baozi_make2=producer('mahzongyi1',que)

baozi_make2.start()

baozi_make3=producer('mahzongyi2',que)

baozi_make3.start()

for item in range(20):

name = 'lazup%d'%(item)

temp=consumer(name,que)

temp.start()

NSCondition 多執行緒解決生產者消費者問題

import viewcontroller.h inte ce viewcontroller 資料緩衝區 property strong,nonatomic nsmutablearray products 執行緒鎖 property strong,nonatomic nscondition cond...

多執行緒 生產者和消費者

生產者 消費者問題 生產者向產品區里放產品,當產品區里滿了,需要等待 消費者從產品區里取產品消耗,當產品區里空了,需要等待。public class producerandconsumer 消費者 static class consumer implements runnable catch int...

執行緒中生產者和消費者

package com.thread.p c public class valueobject package com.thread.p c public class p public void setvalue string value system.currenttimemillis syste...