import os print('starting...') os.fork() #生成子进程,后续代码在父子进程中运行 print('Hello Word!') #可以根据fork()的返回值判断是父进程还是子进程 # [root@zhuji pyrhon百例]# python3 101多进程.py # starting... # Hello Word! # Hello Word! #fork()后会出现子进程,父子进程都会打印Hello Word!,所以会打印两行Hello Word! import os print('starting...') pid = os.fork() #返回值是一个数值,对于父进程,返回值是子进程的PID,子进程是0 if pid: #如果pid不为0,则执行父进程,为0则执行子进程 print('In parent') #父进程执行的代码 else: print('In Child') #子进程执行的代码 print('Done...') #父子进程都会执行的代码 # [root@zhuji pyrhon百例]# python3 101多进程.py # starting... # In parent # Done... # In Child # Done... # 多进程编程时,要明确父子进程的工作。如:父进程只用于fork子进程; # 子进程做具体的工作,如果在循环结构中,做完后要退出,否则子进程还会再产生子进程、孙进程……,系统会崩溃。 import os for i in range(5): pid = os.fork() #父进程执行的工作是生成子进程,子进程再执行代码 if not pid: #not pid,为真即pid为0,执行下面的代码,也就是子进程执行代码 print('hello') #exit() #子进程执行完以后关闭 # 加上了,exit(),若不加则会打印很多的hello # [root@zhuji pyrhon百例]# python3 101多进程.py # hello # hello # hello # hello # hello #多进程的ping #没有多进程,ping一个网段的IP地址往往要花费几十分钟;使用多进程,几秒钟解决。 import subprocess import os def ping(host): rc = subprocess.call( #执行shell命令 'ping -c2 %s &> /dev/null' % host, shell=True #固定格式 ) if rc: print('%s:down' % host) else: print('%s:up' % host) if __name__ == '__main__': ips = ('192.168.1.%s' % i for i in range(1,255)) for ip in ips: pid = os.fork() if not pid: ping(ip) exit() #多进程的效率 # 没有多进程,即使CPU有多个核心,程序只是运行在一个核心上,无法利用多进程提升效率。 # 5000万次加法,如果需要2.5秒,调用两次共花费5秒。 import time def calc(): result = 0 for i in range(1,50000001): result += i print(result) if __name__ == '__main__': start = time.time() calc() calc() end = time.time() print(end - start) # [root@room9pc01 untitled]# python3 101多进程.py # 1250000025000000 # 1250000025000000 # 3.690995693206787 #通过多进程,程序运行在多个核心上, # 同样的调用两次5000万次加法运算,时间仅为一半 import time import os def calc(): result = 0 for i in range(1,50000001): result += i print(result) if __name__ == '__main__': start = time.time() for i in range(2): pid = os.fork() if not pid: calc() exit() os.waitpid(-1,0) #挂起父进程,直到子进程结束才继续向下执行 os.waitpid(-1,0) #每个waitpid只能处理一个僵尸进程,两个子进程需要调用两次 end = time.time() print(end - start) # [root@room9pc01 untitled]# python3 101多进程.py # 1250000025000000 # 1250000025000000 # 1.9002265930175781 #僵尸进程 #多进程编程要注意僵尸进程。子进程没有可执行代码后将变成僵尸进程, # 如果父进程一直运行,又没有处理僵尸进程的代码,僵尸进程也将一直存在, # 消耗资源。僵尸进程无法通过kill命令杀掉。 import os import time pid = os.fork() if pid: print('In parent. sleeping...') time.sleep(60) print('parent done.') else: print('in child. sleeping...') time.sleep(10) print('child done') #10秒后,子进程变成了僵尸进程 #watch -n1 ps a #每隔1秒,执行一次ps a ,当子进程为僵尸进程时显示为z #解决僵尸进程问题 #os.waitpid()的第2个参数,0表示挂起父进程,1表示不挂起父进程。 import os import time pid = os.fork() if pid: print('In parent. sleeping...') print(os.waitpid(-1,1)) #无僵尸u进程可以处理,返回0、 time.sleep(20) print(os.waitpid(-1,1)) #处理僵尸进程,返回子进程pid time.sleep(60) print('parent done.') else: print('in child. sleeping...') time.sleep(10) print('child done') #基于多进程的时间消息服务器 # 1、支持多客户端同时访问 # 2、客户端向服务器发送消息后,服务器把消息加上时间发回客户端 # 3、每个客户端断开后会产生僵尸进程,新客户端连接时销毁所有的僵尸进程 import socket import os from time import strftime class TcpTimeServer: def __init__(self,host='',port=12345): self.addr = (host,port) self.serv = socket.socket() self.serv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) self.serv.bind(self.addr) self.serv.listen(1) def chat(self,c_sock): while True: data = c_sock.recv(1024) if data.strip() == b'quit': break data = '[%s] %s' % (strftime('%H:%M:%S'),data.decode('utf8')) c_sock.send(data.encode('utf8')) c_sock.close() def mainloop(self): while True: cli_sock,cli_addr = self.serv.accept() pid = os.fork() if pid: cli_sock.close() while True: result = os.waitpid(-1,1)[0] if result == 0: break else: self.serv.close() self.chat(cli_sock) exit() self.serv.close() if __name__ == '__main__': s = TcpTimeServer() s.mainloop() #基于多线程的ping # 多线程与多进程类似,但是每个线程没有自己的资源空间,它们共用进程的资源。 # 多线程没有僵尸进程的问题。 import subprocess import threading def ping(host): rc = subprocess.call( 'ping -c2 %s &> /dev/null' % host, shell=True ) if rc: print('%s: down' % host) else: print('%s: up' % host) if __name__ == '__main__': ips = ['192.168.4.%s' % i for i in range(1,255)] for ip in ips: t = threading.Thread(target=ping,args=(ip,)) t.start() #多线程的效率 #python的多线程有一个GIL(全局解释器锁),使得多个线程, # 某一时刻只有一个线程发送给CPU处理。所以多线程不适用计算密集型应用, # 更适合IO密集型应用。 #以下两次计算5000万次加法运算和不用多线程相比,没有效率的提升。 # 因为CPU有上下文切换,甚至可能多线程更慢 import time import threading def calc(): result = 0 for i in range(1,50000001): result += i print(result) if __name__ == '__main__': start = time.time() t1 = threading.Thread(target=calc) t1.start() t2 = threading.Thread(target=calc) t2.start() t1.join() #挂起主进程,当t1线程执行完后才继续向下执行 t2.join() end = time.time() print(end - start) # [root@room9pc01 untitled]# python3 101多进程.py # 1250000025000000 # 1250000025000000 # 3.826401948928833 #基于多线程的时间消息服务器 import socket import threading from time import strftime class TcpTimeServer: def __init__(self,host='',port=12345): self.addr = (host,port) self.serv = socket.socket() self.serv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) self.serv.bind(self.addr) self.serv.listen(1) def chat(self,c_sock): while True: data = c_sock.recv(1024) if data.strip() == b'quit': break data = '[%s] %s' % (strftime('%H:%M:%S'),data.decode('utf8')) c_sock.send(data.encode('utf8')) c_sock.close() def mainloop(self): while True: cli_sock,cli_addr = self.serv.accept() t = threading.Thread(target=self.chat,args=(cli_sock,)) t.start() self.serv.close() if __name__ == '__main__': s = TcpTimeServer() s.mainloop()
python-多进程(101)
最新推荐文章于 2022-11-28 17:24:00 发布