多线程(thread+queue 售票)

一、理解

如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。
可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。

Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import time
 5 from threading import Thread
 6 from queue import Queue
 7 
 8 tickets = 100
 9 # 队列中,可以放任意类型的数据,线程安全
10 tickets_queue = Queue(100)
11 # 声明退出条件
12 exitFlag = False
13 
14 
15 class TicketsThread(Thread):
16 
17     def __init__(self, thread_id, sell_tickets_queue):
18         super().__init__()
19         self.thread_id = thread_id
20         self.sell_tickets_queue = sell_tickets_queue
21 
22     # 代码在run中执行,run中完善功能
23     def run(self):
24         super().run()
25         global tickets
26         global exitFlag
27         while True:
28             # 线程退出的条件
29             if exitFlag:
30                 break
31 
32             # 获取队列中数据
33             # Queue特点,取出来,没了
34             try:
35                 tickets = self.sell_tickets_queue.get(block=False)
36                 print('线程:--------%d--------已卖票:%d' % (self.thread_id, tickets))
37                 time.sleep(1)
38                 # 通知队列,任务结束
39                 self.sell_tickets_queue.task_done()
40             except Exception as e:
41                 pass
42 
43 
44 if __name__ == '__main__':
45     '''
46     多个线程,执行同一个任务
47     100url,一个线程,可以
48     10个线程,执行现在请求,优化
49     卖票,多线程
50     10个窗口帮助我们卖票
51     '''
52     for i in range(1, 101):
53         # 向队列中放入100张票
54         tickets_queue.put(i)
55 
56     # 创建10个线程,让10个线程一起执行买票
57     for i in range(1, 11):
58         # 创建卖票线程,并且启动
59         my_thread = TicketsThread(i, tickets_queue)
60         # 启动,线程中的run方法,就开始执行
61         my_thread.start()
62 
63     # join():判断队列是否为空,如果为空,程序继续向下执行,如果不为空,继续等待。(可以理解为队列锁)
64     tickets_queue.join()
65     exitFlag = True
多线程+队列锁=>买票



原文地址:https://www.cnblogs.com/linpd/p/10061028.html