다음 코드는 Raymond's Pycon keynotes on cuncurrency에서 제공됩니다. 그것은 조금 긴, 그래서 나는 질문을 시작합니다 :는 큐에 함께 추가됩니다메시지 대기열을 사용하는 스레드 동기화가 올바르지 않습니다.
- 하면 메시지 및 스레드가있는 오는 방법, 완료로 간주되기 전에 모두 인쇄한다 얼룩덜룩 한 인쇄 된? 스레드 초기화 사이에 100ms 지연을 추가하면이 문제가 해결되며 예상대로 출력됩니다.
-
import Queue, time
counter_queue = Queue.Queue()
counter = 0
def counter_manager():
# I have EXCLUSIVE rights to update the counter variable
global counter
while True:
increment = counter_queue.get()
counter += 1
print_queue.put(['The count is {}\n'.format(counter),
'----------\n'])
counter_queue.task_done()
t = threading.Thread(target=counter_manager)
t.daemon = True
t.start()
del t
print_queue = Queue.Queue()
def print_manager():
# I have EXCLUSIVE rights to call the print keyword
while True:
job = print_queue.get()
for line in job:
print line
print_queue.task_done()
t = threading.Thread(target=print_manager)
t.daemon = True
t.start()
del t
def worker_threads():
counter_queue.put(1)
print_queue.put(['Starting up.. with message queues'])
worker_threads = []
for i in range(10):
t = threading.Thread(target=worker)
worker_threads.append(t)
t.start()
# time.sleep(0.1)
for t in worker_threads:
t.join()
counter_queue.join()
print_queue.put(['Finishing up'])
print_queue.join()
그것은 작업자 스레드에서 메시지를 수신하고, 순차적으로 실행하는 데몬으로 counter_manager
및 print_queue
를 사용합니다. 내가 알기에 이것은 실행의 순서를 유지해야한다. 그러나 다음과 같은 출력이 표시됩니다.
Starting up.. with message queues
The couns is 1The couns is 2
--------------------
The couns is 3
----------The couns is 4
The couns is 5
The couns is 6
----------
----------
----------
The couns is 7
----------The couns is 8
The couns is 9----------
----------The couns is 10
----------
Finishing up
카운터가 올바르게 증가하지만 여전히 인쇄 메시지가 스크래블됩니다. 나는 잠 문을 주석 처리를 제거하면
, 스레드 초기화가 100ms의 지연되고 출력 큐를 사용
Starting up.. with message queues
The couns is 1
----------
The couns is 2
----------
The couns is 3
----------
The couns is 4
----------
The couns is 5
----------
The couns is 6
----------
The couns is 7
----------
The couns is 8
----------
The couns is 9
----------
The couns is 10
----------
Finishing up
올바른지, 인쇄 순서에 있어야합니다. 맞지 않아?
작업자 코드는
def worker():
global counter
counter += 1
print 'The couns is {}'.format(counter) # read the var (race cond.)
print '----------'
와우, 고마워! 작업자 함수를 다른 파트의 파일로 정의하고 사용하고있었습니다. 나는 실수로'worker_threads' 대신에'worker'를 넣습니다. – Vinny
@Vinny'worker'의 정의를 포함시킬 수 있습니까? 'worker_threads'는리스트로 정의되기 때문에'worker_threads'는'Thread''' target으로 동작하지 않습니다. – ryachza
나는 그것을 추가했다. 작업자 방법은 불안정하지 않습니다. 경쟁 조건을 생성하고 메시지 대기열을 사용하여 해결합니다. – Vinny