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

输出有“couns”,但代码显示“count”。你可以验证你提供的输出和代码是否一致?

您的输出似乎只在行级交错。

我不知道以前版本的代码在counter_manager中有两个不同的.put(不是原子的),后来被合并为一个具有多行的.put

+0

哇,谢谢!我已经定义了一个工作函数文件在不同的部分,并正在使用它。我错误地把'worker'而不是'worker_threads' – Vinny

+0

@Vinny然后你可以包含'worker'的定义吗? 'worker_threads'不能作为'Thread'' target'工作,因为'worker_threads'也被定义为一个列表。 – ryachza

+0

我加了。工作人员的方法并不是无法回避的。它用于创建竞争条件,并使用消息队列解决它 – Vinny