1.线程间的通信方式
1.共享全局变量
2.线程队列(queue)
3.信号量(Semaphore)
2.共享全局变量进行通信
from threading import Thread import time g_nums = [11,22,33] def work1(nums): nums.append(44) print("----in work1---",nums) def work2(nums): #延时一会,保证t1线程中的事情做完 time.sleep(1) print("----in work2---",nums) t1 = Thread(target=work1, args=(g_nums,)) t1.start() t2 = Thread(target=work2, args=(g_nums,)) t2.start()
3.共享全局变量的资源竞争
# 多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确 import threading import time g_num = 0 def work1(num): global g_num for i in range(num): g_num += 1 print("----in work1, g_num is %d---" % g_num) def work2(num): global g_num for i in range(num): g_num += 1 print("----in work2, g_num is %d---" % g_num) print("---线程创建之前g_num is %d---" % g_num) t1 = threading.Thread(target=work1, args=(1000000,)) t1.start() t2 = threading.Thread(target=work2, args=(1000000,)) t2.start() while len(threading.enumerate()) != 1: time.sleep(1) print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
4.线程队列queue.Queue-生产者消费者模式
from threading import Thread import queue from time import sleep # 生产者 class Producer(Thread): def run(self): count = 0 while True: if q.qsize() < 50: for i in range(3): count += 1 msg = "产品%d" % count # 将产品放入队列 q.put(msg) # print("生产了: %s 还有%s个" % (msg, q.qsize())) sleep(1) # 消费者 class Customer(Thread): def run(self): while True: if q.qsize() > 20: for i in range(2): msg = q.get() # 从仓库中拿货 print("消耗了: %s 还有%s个" % (msg, q.qsize())) sleep(1) def main(): # 创建一个队列仓库 global q q = queue.Queue() # 创建2个生产 for i in range(2): p = Producer() p.start() # 创建3个消费 for i in range(3): c = Customer() c.start() if __name__ == "__main__": main() """执行结果 消耗了: 产品1 还有20个 消耗了: 产品2 还有22个 消耗了: 产品3 还有24个 消耗了: 产品1 还有23个 消耗了: 产品2 还有25个 消耗了: 产品3 还有24个 消耗了: 产品4 还有23个 消耗了: 产品5 还有22个 """
5.线程队列-先进先出队列,后进先出队列,优先级队列
from multiprocessing import Queue # 是用于多进程的队列,就是专门用来做进程间通信(IPC) import queue # 是用于同一进程内的队列,不能做多进程之间的通信 q = queue.Queue() # 先进先出 q.put(1) q.put(2) q.put(3) print(q.get()) print(q.get()) q = queue.LifoQueue() # 后进先出的队列 q.put(1) q.put(2) q.put(3) print(q.get()) q = queue.PriorityQueue() # 优先级队列,put()方法接收的是一个元组(),第一个位置是优先级,第二个位置是数据 # 优先级如果是数字,直接比较数值 # 如果是字符串,是按照 ASCII 码比较的,当ASCII码相同时,会按照先进先出的原则 q.put((1, 'abc')) q.put((5, 'qwe')) q.put((-5, 'zxc')) print(q.get()) print(q.get())
6.信号量-Semaphore
from threading import Semaphore from threading import Thread import time def func(sem, i): sem.acquire() print('第%s个人进入屋子' % i) time.sleep(2) print('第%s个人离开屋子' % i) sem.release() sem = Semaphore(5) for i in range(20): t = Thread(target=func, args=(sem, i)) t.start()