我遇到了多處理模塊的麻煩。我有使用鎖,但下面的代碼仍然不安全,我不知道爲什麼,有時計數器不會等於100,我該如何修復代碼讓它安全?python多處理共享變量保險箱
import random
import threading
from multiprocessing import Pool, Manager
import time
lock = threading.Lock()
def a_complex_operation(counter):
with lock:
time.sleep(random.random())
counter.value += 1
def main():
pool = Pool(16)
counter = Manager().Value('i', 0)
for i in range(100):
pool.apply_async(a_complex_operation, args=(counter,))
pool.close()
pool.join()
if counter.value != 100:
print "not equal 100, current value is: "+str(counter.value)
if __name__ == '__main__':
count = 0
while True:
t1 = time.time()
main()
count += 1
print "the " + str(count) + " loop, cost time: " + str(time.time() - t1)
的輸出將是:。
the 1 loop, cost time: 4.1369998455
the 2 loop, cost time: 3.74100017548
the 3 loop, cost time: 3.92299985886
the 4 loop, cost time: 4.05500006676
not equal 100, current value is: 99
the 5 loop, cost time: 4.01900005341
the 6 loop, cost time: 4.14299988747
然後我測試管理器()列表()和管理器()值( 'I',0)一起
import random
from multiprocessing import Pool, Manager
import time
def a_complex_operation(list_, counter):
for x in range(10):
time.sleep(random.random()/10)
list_.append(x)
counter.value += 1
def main():
pool = Pool(16)
counter0 = 0
list_ = Manager().list()
counter = Manager().Value('i', 0)
for i in range(100):
pool.apply_async(a_complex_operation, args=(list_, counter))
counter0 += 1
pool.close()
pool.join()
if len(list_) != 1000:
print "length of list is not equal 1000, current is:" + str(len(list_))
if counter.value != 1000:
print "value of counter is not equal 1000, current is :" + str(counter.value)
if __name__ == '__main__':
counter = 0
while True:
counter += 1
t1 = time.time()
main()
t2 = time.time()
print "the " + str(counter) + " loop cost time: " + str(t2 - t1)
的輸出結果如下:
value of counter is not equal 1000, current is :916
the 1 loop cost time: 3.92299985886
value of counter is not equal 1000, current is :911
the 2 loop cost time: 3.98500013351
value of counter is not equal 1000, current is :925
the 3 loop cost time: 4.007999897
value of counter is not equal 1000, current is :913
the 4 loop cost time: 3.99399995804
value of counter is not equal 1000, current is :920
the 5 loop cost time: 4.09500002861
value of counter is not equal 1000, current is :915
我覺得Manager().list()是安全的,Man價值('我',0)是不安全的,有趣的,任何人都可以告訴我爲什麼經理()。列表()看起來像安全嗎?
你可以通過將'time.sleep(random.random())'放在外面「來加速它。 – gzc
當然。我假設OP只是使用睡眠來模擬需要一些時間的操作。我的評論只是爲了提醒這一點。在原始消息中,代碼每次迭代需要幾秒鐘,因爲鎖定什麼都不做,並且總是可以被獲取。在我的解決方案鎖定工作,但運行時間增加了很多,因爲它應該。 (最初當我測試它在頭幾秒沒有發生任何事情,我認爲有一個僵局......只是爲了找出我沒有耐心) – Hannu
我認爲@ gzc是正確的 – bill