import threading import time import queue # 线程队列 '''多线程不使用任何锁的情况下,对同一个列表进行删除操作(列表是不安全的数据结构)''' # l = [1, 2, 3, 4, 5, 6] # def num(): # while l: # a = l[-1] # print(a) # time.sleep(0.5) # try: # l.remove(a) # except Exception as e: # print(e) # if __name__ == '__main__': # t1 = threading.Thread(target=num) # t2 = threading.Thread(target=num) # t1.start() # t2.start() # t1.join() # t2.join() # print('ending...') # 最后一个元素两个线程都取到了,进行删除操作时有一个线程先执行,而后执行的线程由于列表最后一个元素已经被前一个线程删除了,所以报错list.remove(x): x not in list '''线程队列''' q = queue.Queue(3) # Queue()是先进先出,maxsize参数代表只能put3个数据(默认参数maxsize=0,代表无限),当超过3个数据时,程序卡在了最后一个put且不往下执行,其它线程可以进行get从而才可以继续往下执行 q.put(1) q.put('alex') q.put({'name: mike'}) # q.put(1, block=False) # 如果block==False(默认为True),那么put超过指定数量(maxsize)时,会自动报错:queue.Full;另一种写法q.put_nowait(item) print(q.qsize()) # qsize()是按照队列有多少数据来进行统计,并不是根据maxsize print(q.empty()) # empty()判断队列是否为空,是则返回True,反之False print(q.full()) # full()判断队列是否填充满,是则返回True,反之False # q.task_done()表示前面排队的任务已经被完成。被队列的消费者线程使用。每个 get() 被用于获取一个任务, 后续调用 task_done() 告诉队列,该任务的处理已经完成。如果 join() 当前正在阻塞,在所有条目都被处理后,将解除阻塞(意味着每个 put() 进队列的条目的 task_done() 都被收到)。如果被调用的次数多于放入队列中的项目数量,将引发 ValueError 异常 # q.join()阻塞至队列中所有的元素都被接收和处理完毕。当条目添加到队列的时候,未完成任务的计数就会增加。每当消费者线程调用 task_done() 表示这个条目已经被回收,该条目所有工作已经完成,未完成计数就会减少。当未完成计数降到零的时候, join() 阻塞被解除 while True: data = q.get(block=False) # 当get完最后一个数据时,程序仍未结束,可以理解为当队列还有数据put时还能继续get;如果block==False(默认为True),没有数据get时报错:_queue.Empty;另一种写法q.get_nowait() print(data) print('------') # q = queue.LifoQueue() # LifoQueue()是后进先出(先进后出) # q.put(1) # q.put('alex') # q.put({'name: mike'}) # # while True: # data = q.get() # print(data) # print('------') # q = queue.PriorityQueue() # Priority优先,按优先级,数字越小优先级越高(第一个索引就是代表优先级),如果优先级重复会报错:TypeError: '<' not supported between instances of 'set' and 'str' # q.put([1, 2]) # q.put([3, 'alex']) # q.put([2, {'name: mike'}]) # # while True: # data = q.get() # print(data[1]) # print('------')