进程间通信--消息队列--共享内存--线程基础

    xiaoxiao2023-10-20  174

    进程间通信

    消息队列 Queue 通信原理:在内存中建立队列模型,进程通过队列存取消息实现通信, 实现方法:

    from multiprocessing import Queue q = Queue(maxsize = 0) 功能:创建消息队列 参数:最多存放多少消息 q.put(data,[block,timeout]) 功能:向队列存入消息 参数:data 要存入的数据 block False为非阻塞 timeout 超时时间 q.get([block,timeout]) 功能:从队列中取出消息 参数:block False为非阻塞 timeout 超时时间 q.full() 判断队列是否为满 q.empty() 判断队列是否为空 q.qsize() 获取队列中消息个数 q.close() 关闭队列

    代码部分

    from multiprocessing import Queue,Process from time import sleep # 创建消息队列 q = Queue(3) def fun1(): for i in range(3): sleep(1) q.put((1,3)) def fun2(): for i in range(4): try: a,b = q.get(timeout = 3) except: return print("sum = ",a+b) p1 = Process(target=fun1) p2 = Process(target=fun2) p1.start() p2.start() p1.join() p2.join()

    共享内存 Value 通信原理:在内存中开辟一块空间,进程可以写入和读取内容,但是每次写入内容都会覆盖之前内容 实现方法::

    from multiprocessing import Value,Array obj = Value(ctype,data) 功能:创建共享内存 参数:ctype 共享内存类型 data 共享内存初始数据 obj.value 对该属性修改查看即共享内存读写 obj = Aeeay(ctype,data) 功能:创建共享内存 参数:ctype 共享内存类型 i整数 c单个字符 data 列表表示共享内存初始数据,整数表示共享内存开辟数据元素个数 obj进行遍历或者索引方式获取值,也可通过索引直接赋值。 obj.value 用于整体打印共享内存中字节串 from multiprocessing import Process,Value import time,random # 创建共享内存 money = Value("i",5000) # 操作共享内存 def man(): for i in range(30): time.sleep(0.2) money.value += random.randint(1,1000) def girl(): for i in range(30): time.sleep(0.18) money.value -= random.randint(100,800) m = Process(target=man) g= Process(target=girl) m.start() g.start() m.join() g.join() print("一月余额:",money.value)

    信号量(信号灯集) 通信原理:给定一个数量对多个进程可见,多个进程都可以操作数量的增减,并根据数量决定行为, 实现方法

    from multiprocessing import Semaphoer sem = semaphoer(num) 功能:创建信号量对象 参数:信号量初始值 返回值:信号量对象 sem.acquire() 消耗一个信号量,当信号量为0时阻塞。 sem.get_value() 获取信号值 sem.release() 增加一个信号量

    注意:当在父进程中创建对象(文件对象,套接字对象,进程间通信对象), 子进程从父进程中拷贝对象时父子进程对该进程的使用会有属性的相互影响,如果在父子进程中各自创建,则无影响。

    from multiprocessing import Semaphore,Process from time import sleep import os # 创建信号量 sem = Semaphore(3) # 系统中最多有3个进程同时执行该事件 def fun(): sem.acquire()#消耗一个信号量 print("%d执行事件"%os.getpid()) sleep(3) print("%d执行完毕"%os.getpid()) sem.release()#增加信号量 jobs = [] for i in range(5): p = Process(target=fun) jobs.append(p) p.start() for i in jobs: i.join() print(sem.get_value())

    二、线程编程(Thread)

    什么是线程 线程被称为轻量级的进程 线程也是多任务编程方法,可以使用计算机多核资源 线程是系统分配内核的最小单元 线程可以理解为进程中的任务分支程序线程的特征 一个进程可以包含多个线程 线程也是一个运行过程,消耗计算机资源 一个进程中的所有线程共享这个进程资源 线程的创建和消耗 消耗资源远小于进程 线程也自己的特有属性特征命令,id等threading模块创建线程 创建线程对象 from threading import Thread t = Thread() 功能:创建线程对象 参数:target 绑定的线程函数 args元组 给线程函数传参 kwargs字典 给线程函数关键字传参 启动线程 t.start() 阻塞等待回收线程 t.join([timeout]) from threading import Thread from time import sleep # 含有参数的线程函数 def fun(sec,name): print("线程函数传参") sleep(sec) print("%s 线程传参完毕"%name) threads = [] for i in range(5): t = Thread(target=fun,args=(2,),kwargs={"name":"T%d"%i}) threads.append(t) t.start() # t.join() for i in threads: i.join() ``` from threading import Thread from time import sleep import os a= 1 def music(): global a print("a=",a) a = 10000 for i in range(5): sleep(2) print("命运交响曲",os.getpid()) t = Thread(target = music) t.start() for i in range(3): sleep(3) print("喜洋洋",os.getpid()) t.join() print("aaa=",a) ``` 线程对象属性 t.name 线程名称 t.setName() 设置线程名称 t.getname() 获取线程名称 t.is_alive() 查看线程是否在生命周期 t.daemon 设置主线程和分支线程的退出关系 t.setDaemon() 设置daemon属性值 t.isDaemon() 查看daemon属性值 **设置daemon为True 此时追按成退出分支线程也会退出,设置在start前完成,不和join 同用自定义线程类 创建步骤 继承Thread类 重写__init__方法,添加自己的属性,执行父类的__init__ 重写run 方法 使用: 实例化线程对象 调用start自动执行run join回收进程from threading import Thread from time import ctime,sleep class MyThread(Thread): def __init__(self,target,args=(),kwargs={}): self.target = target self.args = args self.kwargs = kwargs super().__init__() def run(self): self.target(*self.args,**self.kwargs) # def player(sec,song): for i in range(2): print("playing %s:%s"%(song,ctime())) sleep(sec) t = MyThread(target=player,args=(3,),kwargs={"song":"凉凉"}) t.start() t.join()

    线程通信

    通信方法:线程间使用全局变量进行通信 共享资源的争夺 共享资源:多个进程或者线程都可以操作的资源成为共享资源 影响:对共享资源的无序操作可能会带来数据的混乱或者操作错误,此时需要同步互斥机制处理同步互斥机制 同步:同步是一种协作关系,为完成操作,多进程或者线程间形成一种协调,按照必要的步骤执行操作。 互斥:互斥是一种制约关系,当一个进程或者线程抢占到资源时进行加锁处理,其他进程线程就无法操作资源,直到解锁后才能操作

    线程互斥方法:

    线程Event from threading import Event e = Event() #创建线程Event对象 e.wait([timeout]) #阻塞等待直到e被set e.set() #设置e,使wait结束阻塞 e.clear() #清楚e 的设置,wait会阻塞 e.is_set() #判断e 的状态

    from threading import Event,Thread from time import sleep s = None e = Event() #创建event对象 def yang(): # sleep(0.2) print("杨子荣拜山头") global s s = "天王盖地虎" e.set() f = Thread(target = yang) f.start() # 验证口令 print("说对口令就是自己人") # sleep(2) e.wait() #添加阻塞 if s == "天王盖地虎": print("确认") else: print("打死他") f.join()
    最新回复(0)