行走的小菜頭
阿新 • • 發佈:2018-12-20
from threading import Thread
import time
#1. 如果多個執行緒執行的都是同一個函式的話,各自之間不會有影響,各是個的
def test(arg):
time.sleep(1)
print("thread"+str(arg))
for i in range(5): #5個執行緒同時執行
t = Thread(target=test,args=(i,))
t.start()
結果:
thread0
thread2
thread1
thread3
thread4
執行緒程式碼的封裝:
import threading,time class MyThread(threading.Thread): def run(self): for i in range(5): time.sleep(1) print('I`m '+self.name+ '程序 '+str(i)) #name當前的執行緒名 if __name__=='__main__': t=MyThread() t.start()
多執行緒間共享全域性變數,造成對共享資料的出錯,使用互斥鎖,給各個程序上鎖,當這個程序釋放後,下一個程序才開始執行,依次迴圈,保護好共享的安全性。
#多執行緒間共享資料出錯: from threading import Thread import time g_num = 0 #全域性變數 def test1(): global g_num for i in range(1000000): g_num += 1 print("---test1---g_num=%d"%g_num) def test2(): global g_num for i in range(1000000): g_num += 1 print("---test2---g_num=%d"%g_num) p1 = Thread(target=test1) p1.start() #time.sleep(3) #取消遮蔽之後 再次執行程式,資料就不會變化,因為test1程序在3s內足夠執行完,不造成資料的錯亂。 p2 = Thread(target=test2) p2.start() print("---g_num=%d---"%g_num) 結果: ---g_num=234497--- ---test1---g_num=1143699 ---test2---g_num=1342951
#使用互斥鎖: from threading import Thread, Lock import time g_num = 0 def test1(): global g_num #這個執行緒和test2執行緒都在搶著 對這個鎖 進行上鎖,如果有一方成功的上鎖,那麼導致另外一方會堵塞(一直等待)到這個鎖被解開為止 mutex.acquire() for i in range(1000000): g_num += 1 mutex.release() #用來對mutex指向的這個鎖 進行解鎖,,,只要開了鎖,那麼接下來會讓所有因為這個鎖 被上了鎖 而堵塞的執行緒 進行搶著上鎖 print("---test1---g_num=%d"%g_num) def test2(): global g_num mutex.acquire() for i in range(1000000): g_num += 1 mutex.release() print("---test2---g_num=%d"%g_num) #建立一把互斥鎖,這個鎖預設是沒有上鎖的 mutex = Lock() p1 = Thread(target=test1) p1.start() #time.sleep(3) #取消遮蔽之後 再次執行程式,結果會不一樣,,,為啥呢? p2 = Thread(target=test2) p2.start() print("---g_num=%d---"%g_num) #互斥鎖放到for迴圈裡,最後是200萬,第一個都在執行
-
同步:
同步就是協同步調,按預定的先後次序進行執行如:你說完,我再說。
如程序,執行緒同步,可理解為程序或執行緒甲和乙一塊配合,A執行到一定程度時要依靠乙的某個結果,於是停下來,示意乙執行;乙依言執行,再將結果給阿; A再繼續操作。
from threading import Thread,Lock
from time import sleep
class Task1(Thread):
def run(self):
while True:
if lock1.acquire():
print("------Task 1 -----")
sleep(0.5)
lock2.release()
class Task2(Thread):
def run(self):
while True:
if lock2.acquire():
print("------Task 2 -----")
sleep(0.5)
lock3.release()
class Task3(Thread):
def run(self):
while True:
if lock3.acquire():
print("------Task 3 -----")
sleep(0.5)
lock1.release()
#使用Lock創建出的鎖預設沒有“鎖上”
lock1 = Lock()
#建立另外一把鎖,並且“鎖上”
lock2 = Lock()
lock2.acquire()
#建立另外一把鎖,並且“鎖上”
lock3 = Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()
結果:
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
蟒的佇列模組中提供了同步的,執行緒安全的佇列類,包括FIFO(先入先出)佇列佇列,LIFO(後入先出)佇列LifoQueue,和優先順序佇列PriorityQueue.Queue可以使用佇列來實現執行緒間的同步。
#佇列解耦, - 解決死鎖問題
非同步:
from multiprocessing import Pool
import time
import os
#非同步的理解:主程序正在做某件事情,突然 來了一件更需要立刻去做的事情,
#那麼這種,在父程序去做某件事情的時候 並不知道是什麼時候去做,的模式 就稱為非同步
def test():
print("---程序池中的程序---pid=%d,ppid=%d--"%(os.getpid(),os.getppid()))
for i in range(3):
print("----%d---"%i)
time.sleep(1)
return "hahah"
def test2(args):
print("---callback func--pid=%d"%os.getpid())
print("---callback func--args=%s"%args) #hahah
if __name__ == '__main__':
pool = Pool(3)
pool.apply_async(func=test,callback=test2)
time.sleep(5)
print("----主程序-pid=%d----"%os.getpid())
結果:
---程序池中的程序---pid=7664,ppid=5612--
----0---
----1---
----2---
---callback func--pid=5612
---callback func--args=hahah
----主程序-pid=5612----