主进程建立守护进程(子进程)python
那么主进程就是被守护进程安全
注意:进程之间是相互独立的,主进程代码运行结束,守护进程随即终止.并发
from multiprocessing import Process import time def task(): print('sub start') print('sub over') if __name__ == '__main__': p =Process(target=task) p.daemon = True # 将这个进程设置成子进程,必须放在p.start()前面 p.start() print('parent start') time.sleep(1) # 这里加延时,就是为了让子进程运行完毕,不然,就会出现子进程(守护进程)尚未运行彻底,主程序(被守护进程)就已经运行完并结束代码了 print('parent over') # 若是没有在主程序这里加延时,则不会打印子进程,由于在操做系统开启子进程时,主程序代码已经运行完毕. parent start sub start sub over parent over
由于子进程的内存时相互隔离的,因此进程之间数据不共享;若是多个在子进程同时访问同一个文件,或者打印同一个终端,那么就会带来竞争,竞争带来的结果就是错乱,这个就是进程安全问题.app
这里进程1和进程2,之因此把范围放这么大,是为了能显示出问题打印ui
from multiprocessing import Process def task1(): for i in range(10000): print('sub1 run') print('sub1 over') def task2(): for i in range(10000): print('sub2 run') print('sub2 over') if __name__ == '__main__': p1 = Process(target=task1) p2 = Process(target=task2) p1.start() p2.start() sub1 over sub2 over sub1 run sub2 run sub1 over sub2 over
什么是互斥锁?操作系统
互相排斥的锁code
原理:队列
就是将要操做公共资源的代码锁起来 以保证同一时间只能有一个进程在执行这部分代码进程
进程之间数据不共享,可是共享同一套文件系统,同时访问同一个文件,或者打印同一个终端,那么就会产生竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理ip
为了解决上面出现由于子进程竞争而出现的进程安全问题,为了解决这个问题,咱们用到了互斥锁.
from multiprocessing import Process,Lock def task1(mutex): mutex.acquire() for i in range(10000): print('sub1 run') print('sub1 over') mutex.release() def task2(mutex): mutex.acquire() for i in range(10000): print('sub2 run') print('sub2 over') mutex.release() if __name__ == '__main__': mutex = Lock() p1 = Process(target=task1,args=(mutex,)) p2 = Process(target=task2,args=(mutex,)) p1.start() p2.start()
def task1(): global lock if lock == False: lock = True open("aaa.txt","wt") lock = False def task2(): global lock if lock == False: lock = True open("aaa.txt","wt") lock = False
从这能够看出,锁并非把数据锁住不让用,而是让代码不执行.
多个子进程同时读写一个共享文件,虽然加了锁,但有时也会形成文件错乱问题,由于子进程之间数据不互通,即数据不一样步.那么咱们就须要建立一个同步通道
from multiprocessing import Process,Manager,Lock import time def task(data,lock): lock.acquire() num = data[0] time.sleep(0.2) data[0] = num -1 lock.release() if __name__ == '__main__': d = [100] m = Manager() # 建立一个管理器 sync_list = m.list(d) # 让管理器建立一个进程同步的列表(也能够是字典等) lock = Lock() # 建立一个锁 ps = [] for i in range(10): p = Process(target=task,args=(sync_list,lock)) p.start() ps.append(p) for p in ps:p.join() print(d) print(sync_list) sub over sub over sub over sub over sub over sub over sub over sub over sub over sub over [100] [90]
总结:
加锁能够保证多个进程修改同一块数据时,同一时间只能有一个任务能够进行修改,即将并发改为串行,保证了数据安全,可是牺牲了速度.
虽然能够用文件共享数据实现进程间通讯,但问题是:
这种方式适合交互不频繁,数据量大的状况,
对于交互频繁,数据量小的状况不合适,所以咱们用另一种解决方案:IPC(进程间通讯)--队列+管道
进程间相互隔离,要实现进程间通讯(IPC),multiprocess模块支持两种形式:队列和管道,这两种方式都是使用消息传递的
队列是先进先出
from multiprocessing import Queue q = Queue(2) # 建立队列,而且同时只能存储两个元素,若是不写,默认为无限大 q.put(1) # 将数据存入管道 q.put(2) # q.put(3,block=False,timeout=3) # block=True表示阻塞,默认为True; timeout=3表示等待延时3s,默认为None; # 当容器中没有位置了就阻塞,等待3秒,在这个时间段有人从管道里面取走一个元素, # 那么元素3就会存入进去,不然就会抛出错误 queue.Full print(q.get()) # get 是将数据取出来 而且是先进先出 print(q.get()) # print(q.get(block=True,timeout=3)) # 默认是阻塞,直到有人存入元素, 跟存入同样.