2017-11-14 5 views
0

저는 멀티 스레딩 및 잠금을 보여주는 장난감 예제가 있습니다. 자물쇠가 없다면, 나는 분명히 세계 counter 변수에 대해 나쁜 값을 얻는다. 그러나, threading.Lock을 입력하면 더 많은 불일치가 발생합니다. 또한 multiprocessing.Lock()은 문제를 완전히 해결하지 못합니다.파이썬의 스레딩 및 다중 프로세스 잠금이 작동하지 않습니다.

import threading 
from multiprocessing import Process, Lock 

num_experiments = 200 
num_threads = 5 
iterations_in_one_thread = 500 

def f(): 

    global counter 
    for i in range(iterations_in_one_thread): 
     with lock: 
      counter += 1 

bad_count = 0 
# lock = threading.Lock() 
lock = Lock() 

for x in range(num_experiments): 

    counter = 0 
    threads = [] 
    for i in range(num_threads): 
     t = threading.Thread(target=f) 
     threads.append(t) 
     t.start() 

    for i in threads: 
     t.join() 

    if counter != num_threads * iterations_in_one_thread: 
     bad_count += 1 
     print counter 


print "Bad count:", bad_count 
print "Total runs:", num_experiments 

출력 내가 기대 : Bad count: 0 출력 내가 얻을 : Bad count: 3

(또는 때때로 6 개까지) 나는 당신이 단지를 한 것으로 생각 2.7.3

Python 2.7.13 |Anaconda custom (x86_64)| (default, Dec 20 2016, 23:05:08) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin 
+0

Windows에서 Python 2.7.13에서 코드를 실행하면 0이됩니다. 자물쇠가 없으면 나는 197 개의 나쁜 카운트를 얻는다. – Vinny

답변

1

파이썬에있어 간단한 오타.

for i in threads: 
    t.join() 

그렇지 않으면, 당신은 단지 마지막 스레드에 가입하고

for i in threads: 
    i.join() 

해야한다. 또한 멀티 프로세싱 라이브러리를 스레딩 라이브러리와 함께 사용하지 않아야합니다. 스틱은 threading.Lock입니다.

+0

오 세상에, 어리석은 실수! 고마워. 왜 다중 처리에서 잠금을 사용하는 것이 좋지 않은지에 대해주의를 기울여야합니까? – recluze

+0

그것은 우리 중 최고입니다. 'multiprocessing.Lock'은'threading.Lock'에 가까운 유사점이지만 동일한 것은 아닙니다. 이처럼 간단한 사용법에서는 대개 괜찮을 것입니다 만, 일반적으로'threading'과'multiprocessing'을 혼합하면 추적하기가 어려운 몇 가지 흥미로운 버그가 생길 수 있습니다. –