91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python多線程中阻塞與鎖使用誤區有哪些

發布時間:2021-08-10 12:35:29 來源:億速云 閱讀:122 作者:小新 欄目:開發技術

這篇文章主要介紹了Python多線程中阻塞與鎖使用誤區有哪些,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

關于阻塞主線程

join的錯誤用法

Thread.join() 作用為阻塞主線程,即在子線程未返回的時候,主線程等待其返回然后再繼續執行.

join不能與start在循環里連用
以下為錯誤代碼,代碼創建了5個線程,然后用一個循環激活線程,激活之后令其阻塞主線程.

threads = [Thread() for i in range(5)]
for thread in threads:
 thread.start()
 thread.join()

執行過程:

1. 第一次循環中,主線程通過start函數激活線程1,線程1進行計算.
2. 由于start函數不阻塞主線程,在線程1進行運算的同時,主線程向下執行join函數.
3. 執行join之后,主線程被線程1阻塞,在線程1返回結果之前,主線程無法執行下一輪循環.
4. 線程1計算完成之后,解除對主線程的阻塞.
5. 主線程進入下一輪循環,激活線程2并被其阻塞…

如此往復,可以看出,本來應該并發的五個線程,在這里變成了順序隊列,效率和單線程無異.

join的正確用法

使用兩個循環分別處理start和join函數.即可實現并發.

threads = [Thread() for i in range(5)]
for thread in threads:
 thread.start()
for thread in threads:
 thread.join()

time.sleep代替join進行調試

之前在一些項目里看到過這樣的代碼,使用time.sleep代替join手動阻塞主線程.
在所有子線程返回之前,主線程陷入無線循環而不能退出.

for thread in threads:
 thread.start()
while 1:
 if thread_num == 0:
 break
 time.sleep(0.01)

關于線程鎖(threading.Lock)

單核CPU+PIL是否還需要鎖?

非原子操作 count = count + 1 理論上是線程不安全的.
使用3個線程同時執行上述操作改變全局變量count的值,并查看程序執行結果.
如果結果正確,則表示未出現線程沖突.

使用以下代碼測試

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

import threading
import time
count = 0

class Counter(threading.Thread):
 def __init__(self, name):
 self.thread_name = name
 super(Counter, self).__init__(name=name)

 def run(self):
 global count
 for i in xrange(100000):
  count = count + 1


counters = [Counter('thread:%s' % i) for i in range(5)]
for counter in counters:
 counter.start()

time.sleep(5)
print 'count=%s' % count

運行結果:

count=275552

事實上每次運行結果都不相同且不正確,這證明單核CPU+PIL仍無法保證線程安全,需要加鎖.

加鎖后的正確代碼:

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

import threading
import time

count = 0
lock = threading.Lock()


class Counter(threading.Thread):
 def __init__(self, name):
 self.thread_name = name
 self.lock = threading.Lock()
 super(Counter, self).__init__(name=name)

 def run(self):
 global count
 global lock
 for i in xrange(100000):
  lock.acquire()
  count = count + 1
  lock.release()


counters = [Counter('thread:%s' % i) for i in range(5)]

for counter in counters:
 counter.start()

time.sleep(5)
print 'count=%s' % count

結果:

count=500000

注意鎖的全局性

這是一個簡單的Python語法問題,但在邏輯復雜時有可能被忽略.
要保證鎖對于多個子線程來說是共用的,即不要在Thread的子類內部創建鎖.

以下為錯誤代碼

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

import threading
import time

count = 0
# lock = threading.Lock() # 正確的聲明位置

class Counter(threading.Thread):
 def __init__(self, name):
 self.thread_name = name
 self.lock = threading.Lock() # 錯誤的聲明位置
 super(Counter, self).__init__(name=name)

 def run(self):
 global count
 for i in xrange(100000):
  self.lock.acquire()
  count = count + 1
  self.lock.release()


counters = [Counter('thread:%s' % i) for i in range(5)]

for counter in counters:
 print counter.thread_name
 counter.start()

time.sleep(5)
print 'count=%s' % count

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Python多線程中阻塞與鎖使用誤區有哪些”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湘乡市| 疏附县| 盘山县| 永靖县| 马尔康县| 紫阳县| 浦县| 泰和县| 曲沃县| 略阳县| 巴塘县| 建昌县| 青岛市| 蒙山县| 沙河市| 合山市| 全椒县| 泗阳县| 鄢陵县| 理塘县| 永宁县| 合水县| 满城县| 买车| 朝阳区| 西城区| 甘德县| 墨竹工卡县| 子长县| 开远市| 太白县| 古田县| 西盟| 新宁县| 三明市| 尚义县| 蒙自县| 阜城县| 昌吉市| 高平市| 宁德市|