国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python線程同步的實現代碼

Python線程同步的實現代碼

2021-04-05 00:30Harvard_Fly Python

本文介紹了threading 模塊提供的線程同步原語包括:Lock、RLock、Condition、Event、Semaphore等對象。對大家的學習具有一定的參考學習價值,需要的朋友可以參考下

本文介紹Python中的線程同步對象,主要涉及 thread 和 threading 模塊。

threading 模塊提供的線程同步原語包括:Lock、RLock、Condition、Event、Semaphore等對象。

線程執行

join與setDaemon

子線程在主線程運行結束后,會繼續執行完,如果給子線程設置為守護線程(setDaemon=True),主線程運行結束子線程即結束;

如果join()線程,那么主線程會等待子線程執行完再執行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import threading
import time
 
 
def get_thread_a():
 print("get thread A started")
 time.sleep(3)
 print("get thread A end")
 
 
def get_thread_b():
 print("get thread B started")
 time.sleep(5)
 print("get thread B end")
 
 
if __name__ == "__main__":
 thread_a = threading.Thread(target=get_thread_a)
 thread_b = threading.Thread(target=get_thread_b)
 start_time = time.time()
 thread_b.setDaemon(True)
 thread_a.start()
 thread_b.start()
 thread_a.join()
 
 end_time = time.time()
 print("execution time: {}".format(end_time - start_time))

thread_a是join,首先子線程thread_a執行,thread_b是守護線程,當主線程執行完后,thread_b不會再執行執行結果如下:

get thread A started
get thread B started
get thread A end
execution time: 3.003199815750122

線程同步

當線程間共享全局變量,多個線程對該變量執行不同的操作時,該變量最終的結果可能是不確定的(每次線程執行后的結果不同),如:對count變量執行加減操作 ,count的值是不確定的,要想count的值是一個確定的需對線程執行的代碼段加鎖。

python對線程加鎖主要有Lock和Rlock模塊

Lock: 

?
1
2
3
4
from threading import Lock
lock = Lock()
lock.acquire()
lock.release()

Lock有acquire()和release()方法,這兩個方法必須是成對出現的,acquire()后面必須release()后才能再acquire(),否則會造成死鎖

Rlock:

鑒于Lock可能會造成死鎖的情況,RLock(可重入鎖)對Lock進行了改進,RLock可以在同一個線程里面連續調用多次acquire(),但必須再執行相同次數的release()

?
1
2
3
4
5
6
from threading import RLock
lock = RLock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()

condition(條件變量),線程在執行時,當滿足了特定的條件后,才可以訪問相關的數據

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import threading
 
def get_thread_a(condition):
 with condition:
  condition.wait()
  print("A : Hello B,that's ok")
  condition.notify()
  condition.wait()
  print("A : I'm fine,and you?")
  condition.notify()
  condition.wait()
  print("A : Nice to meet you")
  condition.notify()
  condition.wait()
  print("A : That's all for today")
  condition.notify()
 
def get_thread_b(condition):
 with condition:
  print("B : Hi A, Let's start the conversation")
  condition.notify()
  condition.wait()
  print("B : How are you")
  condition.notify()
  condition.wait()
  print("B : I'm fine too")
  condition.notify()
  condition.wait()
  print("B : Nice to meet you,too")
  condition.notify()
  condition.wait()
  print("B : Oh,goodbye")
 
if __name__ == "__main__":
 condition = threading.Condition()
 thread_a = threading.Thread(target=get_thread_a, args=(condition,))
 thread_b = threading.Thread(target=get_thread_b, args=(condition,))
 thread_a.start()
 thread_b.start()

Condition內部有一把鎖,默認是RLock,在調用wait()和notify()之前必須先調用acquire()獲取這個鎖,才能繼續執行;當wait()和notify()執行完后,需調用release()釋放這個鎖,在執行with condition時,會先執行acquire(),with結束時,執行了release();所以condition有兩層鎖,最底層鎖在調用wait()時會釋放,同時會加一把鎖到等待隊列,等待notify()喚醒釋放鎖

wait() :允許等待某個條件變量的通知,notify()可喚醒

notify(): 喚醒等待隊列wait()

執行結果:

B : Hi A, Let's start the conversation
A : Hello B,that's ok
B : How are you
A : I'm fine,and you?
B : I'm fine too
A : Nice to meet you
B : Nice to meet you,too
A : That's all for today
B : Oh,goodbye

Semaphore(信號量)

用于控制線程的并發數,如爬蟲中請求次數過于頻繁會被禁止ip,每次控制爬取網頁的線程數量可在一定程度上防止ip被禁;文件讀寫中,控制寫線程每次只有一個,讀線程可多個。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time
import threading
 
 
def get_thread_a(semaphore,i):
 time.sleep(1)
 print("get thread : {}".format(i))
 semaphore.release()
 
 
def get_thread_b(semaphore):
 for i in range(10):
  semaphore.acquire()
  thread_a = threading.Thread(target=get_thread_a, args=(semaphore,i))
  thread_a.start()
 
 
if __name__ == "__main__":
 semaphore = threading.Semaphore(2)
 thread_b = threading.Thread(target=get_thread_b, args=(semaphore,))
 thread_b.start()

上述示例了每隔1秒并發兩個線程執行的情況,當調用一次semaphore.acquire()時,Semaphore的數量就減1,直至Semaphore數量為0時被鎖上,當release()后Semaphore數量加1。Semaphore在本質上是調用的Condition,semaphore.acquire()在Semaphore的值為0的條件下會調用Condition.wait(), 否則將值減1,semaphore.release()會將Semaphore的值加1,并調用Condition.notify()

Semaphore源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def acquire(self, blocking=True, timeout=None):
  if not blocking and timeout is not None:
   raise ValueError("can't specify timeout for non-blocking acquire")
  rc = False
  endtime = None
  with self._cond:
   while self._value == 0:
    if not blocking:
     break
    if timeout is not None:
     if endtime is None:
      endtime = _time() + timeout
     else:
      timeout = endtime - _time()
      if timeout <= 0:
       break
    self._cond.wait(timeout)
   else:
    self._value -= 1
    rc = True
  return rc
 
def release(self):
  with self._cond:
   self._value += 1
   self._cond.notify()

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://www.cnblogs.com/FG123/p/9704158.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜在线 | 久久久精品网 | 中文字幕亚洲综合 | 深夜福利影院 | 亚洲伦理一区 | 精品成人av一区二区三区 | 日韩色| 日韩中文一区二区 | 成人av一区二区三区 | 黄色片在线观看视频 | 国产一级片播放 | 欧美日韩精品一区二区在线观看 | 人人人人澡人人爽人人澡 | 一级毛片视频 | 99热精品在线 | 久久久久久久国产精品 | 国产精品国产成人国产三级 | 一本色道久久综合狠狠躁篇的优点 | 嫩草网站在线观看 | 国产亚洲一区二区三区 | 欧美日韩一区二区三区不卡视频 | 特黄视频 | 国产精品乱码人人做人人爱 | 午夜看片在线观看 | 欧美天堂 | 青青草超碰在线 | 亚洲欧美日韩在线 | 亚洲国产精品久久久久 | 狠狠爱综合 | 亚洲专区中文字幕 | 一级大片一级一大片 | 日韩一级片| 天天操天天射天天 | 国产99久久精品 | 久久国产精品一区 | 国产a在亚洲线播放 | 好吊妞国产欧美日韩免费观看视频 | 99re6在线视频精品免费 | 国产精品久久久久久久 | 欧美日韩不卡 | 亚洲国产二区 |