python: 进程 小笔记(1)
进程:一个具有独立功能的程序关于某个数据集合的一次运行活动。 是一堆资源的集合,进程的执行必须在线程的基础上。
进程中最少必须拥有一个线程。
进程与线程的区别?
(1)线程共享内存空间,进程的内存是独立的
(2)同一个进程的线程之间可以直接交流,两个进程想通信,必须通过一个中间代理来实现
(3)创建新线程很简单, 创建新进程需要对其父进程进行一次克隆
(4)一个线程可以控制和操作同一进程里的其他线程,但是进程只能操作子进程
(5)对主线程的修改有可能影响其他线程的运行,对一个父进程的修改不会影响子进程
进程知识点:
(1)进程的创建
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import multiprocessing,threading,os
2 import time
3 def run(name):
4 time.sleep(2)
5 print("****************************************")
6 print("module name :",__name__)
7 print("parent process :", os.getppid())
8 print("process id :", os.getpid())
9 print("process info:",multiprocessing.current_process())
10 print("threading info:",threading.current_thread())#进程里的主线程
11
12 print("[%s] is process"%name)#进程里创建子线程
13 print("****************************************")
14 t = threading.Thread(target=handle , args=(name ,))
15 t.start()
16
17 def handle(name):
18 print("[%s] is thread" % name)
19 print(threading.get_ident())
20
21 if __name__ =='__main__':
22
23 run('main')
24 for i in range(10):
25 p = multiprocessing.Process(target=run , args=(i,))
26 p.start()
(2)子进程与父间的通信
A、进程队列
本质上是两个不同的列表,因为子进程创建的时候把父进程拷贝了一份,底层用pickle将子进程里的q序列化后放在一个两个进程都能碰到的地方, 然后父进程反序列化出来,从而实现了数据的交互。并不是修改同一份数据,只是完成了数据的传递。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import multiprocessing
2
3
4 def run(q):
5 q.put([42,None,'leo'])
6 print("child process :" , id(q))
7
8 if __name__ =="__main__":
9 q = multiprocessing.Queue()
10 p = multiprocessing.Process(target=run , args=(q,))
11 p.start()
12 print(q.get())
13 print("parent process :", id(q))
B、管道pies
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import multiprocessing
2 def run(conn):
3
4 while True:
5 date = conn.recv()
6 print("sub process:%s\n"%date)
7 conn.send(date)
8
9
10 if __name__ =="__main__":
11 parent_conn,sub_conn = multiprocessing.Pipe()
12 p = multiprocessing.Process(target=run , args= (sub_conn,))
13 p.start()
14 while True:
15 com = input("from parent>>\n:")
16 parent_conn.send(com)
17 print("parent process :%s"%parent_conn.recv())
C、Manage
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import multiprocessing,os
2
3 def run(i,d,l,lock):
4 lock.acquire() #锁
5 d[os.getpid()] = i
6 # l.append(os.getpid())
7 for a in range(1000):
8 l[0] +=1
9 print(l)
10 lock.release()
11
12 if __name__ =="__main__":
13 with multiprocessing.Manager() as manager:
14 # 相当于 manager=multiprocessing.Manager()
15
16 d = manager.dict()#生成一个字典,可在多个进程间共享和传递
17 l = manager.list(range(5))
18 p_list=[]
19 lock =multiprocessing.Lock()#进程锁,主要作用是输出屏幕的数据不乱
20 for i in range(10):
21 p = multiprocessing.Process(target=run , args=(i,d,l,lock,))
22 p_list.append(p)
23 p.start()
24
25 for i in p_list: #等待子进程执行完毕
26 i.join()
27
28 print(d)
29 print(l)
(3)进程池
进程池:进程太多,启动时开销太大,导致系统变慢。需要限制每次启动进程的个数。
必须先调用close()再调用join()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import multiprocessing,os,time
2
3 def run(i):
4 time.sleep(2)
5 print("[%s] is processing "%os.getpid())
6 return i+100,'xxxx'
7
8 def Bar(*args):#主进程调用回调
9 print('-->exec done:',args)
10 print('callback from :',multiprocessing.current_process())
11
12 if __name__ == '__main__':
13 pool = multiprocessing.Pool(processes=5) #允许进程池里同时放入5个进程
14
15 for i in range(10):#启动了10个进程,同一时间只有5个进程运行
16 # pool.apply(func=run , args=(i,))#同步执行,串行
17 #pool.apply_async(func=run, args=(i,)) # 异步执行,并行
18 pool.apply_async(func=run, args=(i,),callback=Bar) # 异步执行,并行,callback回调
19
20
21 print('end')
22 pool.close()
23 pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。