目录
(一)我一步你一步
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
加了这俩兄弟就能做一碗吃一碗了
import threading
from queue import Queue
q = Queue()
def producer(name):
count = 1
while count <= 100:
q.join()
q.put(count)
print('{}正在做 第{}碗面条'.format(name, count))
count += 1
def customer(name):
count = 1
while count <= 100:
data = q.get()
print('{}正在吃第{}碗面条'.format(name, data))
count += 1
q.task_done()
def main():
t1 = threading.Thread(target=producer, args=('海参',))
t2 = threading.Thread(target=customer, args=('小包',))
t1.start()
t2.start()
if __name__ == '__main__':
main()
分析:(1)如果producer先抢到CPU,执行到q.join()不用等待可以直接往下执行q.put(count),因为初始队列为空时或者说接到信号时join()才可以直接往下执行。执行到put()放入数据,队列就不为空了,所以xi下一次的循环就卡在join()这一行了,等待消费者将数据取出,然后用q.task_done给你发信号.
(2)如果customer先抢到CPU,执行到q.get()就会等待,因为队列没数据,等生产者将数据放入队列,消费者才会执行
(二)我先走,你就不能比我脚先着地(加锁)
有这么一种情况:
加锁之后的代码:
import threading
from queue import Queue
q = Queue()
def producer(name):
count = 1
while count <= 100:
# q = Queue(), q.join()也会直接执行下去
q.join()
lock1.acquire()
q.put(count)
print('{}正在做 第{}碗面条'.format(name, count))
count += 1
lock1.release()
def customer(name):
count = 1
while count <= 100:
data = q.get()
lock1.acquire()
print('{}正在吃第{}碗面条'.format(name, data))
count += 1
q.task_done()
lock1.release()
def main():
t1 = threading.Thread(target=producer, args=('海参',))
t2 = threading.Thread(target=customer, args=('小包',))
t1.start()
t2.start()
lock1 = threading.Lock()
if __name__ == '__main__':
main()
部分输出: