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_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'而不是'worker_threads' – Vinny
@Vinny然后你可以包含'worker'的定义吗? 'worker_threads'不能作为'Thread'' target'工作,因为'worker_threads'也被定义为一个列表。 – ryachza
我加了。工作人员的方法并不是无法回避的。它用于创建竞争条件,并使用消息队列解决它 – Vinny