0

다음 코드는 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_managerprint_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 '----------' 

답변

2

나는이 문제를 복제 할 수 없습니다. 실행을 위해 threading 가져 오기를 추가하고 worker_threads 함수의 이름을 worker으로 변경했습니다.

출력에 "상담원"이 있지만 코드에 "카운트"가 표시됩니다. 제공하는 출력과 코드가 일치하는지 확인할 수 있습니까?

출력이 회선 수준에서만 인터리브되는 것처럼 보입니다.

코드의 이전 버전이 counter_manager에 두 개의 다른 .put (원자가 아님)이 있고 나중에 여러 줄이있는 단일 .put으로 결합되어 있는지 궁금합니다.

+0

와우, 고마워! 작업자 함수를 다른 파트의 파일로 정의하고 사용하고있었습니다. 나는 실수로'worker_threads' 대신에'worker'를 넣습니다. – Vinny

+0

@Vinny'worker'의 정의를 포함시킬 수 있습니까? 'worker_threads'는리스트로 정의되기 때문에'worker_threads'는'Thread''' target으로 동작하지 않습니다. – ryachza

+0

나는 그것을 추가했다. 작업자 방법은 불안정하지 않습니다. 경쟁 조건을 생성하고 메시지 대기열을 사용하여 해결합니다. – Vinny

관련 문제