进程
什么是进程:
进程就是正在执行的一段程序代码。
进程与程序的关系:
程序只是一堆的代码,而进程是操作系统为这一堆代码执行所创建的内存空间。
进程需要使用的模块:
1 from multiprocessing import Process
该模块下需要掌握的方法:
start()方法--------------->开启进程
1 from multiprocessing import Process 2 import time 3 def test(name): 4 print('%s is running'%name) 5 time.sleep(3) 6 7 if __name__ == '__main__':#在windows系统下,开子进程的代码必须写到这一行下面 8 p = Process(target=test,args=('liuyinzhou',))#创建进程 9 p.start()#开启进程。给操作系统发送一个信号,让操作系统开进程(申请内存+拷贝父进程的地址空间,但该进程执行的时间由操作系统决定 10 print('done')
join()方法----------->等待进程的完成
1 from multiprocessing import Process 2 import os 3 import time 4 def task(): 5 print('run',os.getpid()) 6 time.sleep(3) 7 print('done',os.getpid()) 8 if __name__ == '__main__': 9 p1 = Process(target=task,) 10 p1.start()#父进程等待子进程的完成,直到子进程运行完之后才会执行下面的代码。 11 print('主',os.getpid())
使用进程实现并发
1 from socket import * 2 import threading 3 4 def xiancheng(ip,port): 5 server = socket(AF_INET, SOCK_STREAM) 6 server.bind((ip,port)) 7 server.listen(5) 8 while True: 9 client, add = server.accept() 10 print(add) 11 p = threading.Thread(target=commu, args=(client,)) 12 p.start() 13 server.close() 14 15 def commu(client): 16 while True: 17 try: 18 data_bytes= client.recv(1024) 19 if not data_bytes:break 20 client.send(data_bytes.upper()) 21 except Exception: 22 break 23 client.close() 24 25 if __name__ == '__main__': 26 xiancheng('127.0.0.1',8878)
1 from socket import * 2 client = socket(AF_INET,SOCK_STREAM) 3 ip_port = ('127.0.0.1',8878) 4 client.connect(ip_port) 5 while True: 6 msg = input('>>>:') 7 if not msg :continue 8 client.send(msg.encode('utf-8')) 9 server_data = client.recv(1024) 10 print(server_data.decode('utf-8')) 11 client.close()
存在的问题:
目前确实实现了并发,但是如果有一万个客户端请求,那么就会在服务端创建一万个进程,此时服务端的服务器已经死掉了,因此不行无限制的在客户端开多个进程实现并发。解决的办法是:进程池。
进程池:
1 ''' 2 提交或调用任务的方式: 3 1.同步调用,提交或调用一个任务时,然后在原地等待,等待该任务执行完毕以及拿到结果后,再执行下一个任务 4 2.异步调用:提交或调用一个任务时,不在原地等待,直接执行下面的任务,等所有任务都执行完之后,再调用每次任务的结果 5 ''' 6 from concurrent.futures import ProcessPoolExecutor 7 import time,random,os 8 9 def piao(name,i): 10 print('%s is piaoing %s'%(name,os.getpid())) 11 time.sleep(random.randint(1,4)) 12 return i**2 13 if __name__ == '__main__': 14 15 objs = [] 16 p = ProcessPoolExecutor(5)#创建进程池对象,并指定进程池大小,向操作系统发送创建五个进程信号,等待提交任务 17 # for i in range(10):#使用for循环把任务提交给进程池,但每次只能执行5个进程,操作的对象是进程池(五个进程),不是五个单个的进程 18 # res = p.submit(piao,'alex %s'%i,i).result() ---------------> 同步调用 19 # print(res) 20 21 22 for i in range(10):#使用for循环把任务提交给进程池,但每次只能执行5个进程,操作的对象是进程池(五个进程),不是五个单个的进程 23 obj = p.submit(piao,'alex %s'%i,i) # ---------------> 异步调用 24 objs.append(obj)#------------>每次只是获取进程对象。 25 26 for obj in objs:#只要是某个进程运行完毕,得到结果后就会打印。 27 print(obj.result()) #由于采用异步的调用方式,因此在遍历列表的过程当中有可能某些进程还没有执行完成。 28 29 p.shutdown(wait=True,)#阻止外来任务的提交,等待进程池中的任务都执行完毕,再运行之后的代码 30 print('主进程',os.getpid())
存在的问题:
目前确实解决了之前大量进程对服务器的影响,但是创建进程需要的时间长,解决这一问题的办法就是:线程
注意:
不管是使用进程还是线程实现并发,线程与进程的运行时间都不可控,即不收人为控制,两者的运行时间由操作系统决定。
感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下"推荐"按钮,本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接,谢谢。