Python学习笔记九
Python学习笔记之九
为什么要有操作系统
管理硬件,提供接口。
管理调度进程,并且将多个进程对硬件的竞争变得有序。
操作系统发展史
第一代计算机:真空管和穿孔卡片
没有操作系统,所有的程序设计直接操控硬件
优点:程序员独享整个资源
缺点:浪费资源
第二代计算机:晶体管和批处理系统
优点:计算机资源利用
缺点:程序员共享资源,出现问题,找不出问题,影响开发效率
第三代计算机:集成电路芯片和多道程序设计
多道程序:cpu执行程序的过程中遇到I/O,不会原地等待,cpu会去执行其他命令,等到程序执行完I/O.(时间上的复用)
实现一个看起来像并发。CPU随时切换进程。会影响CPU执行效率。
进程占用一个内存空间,每个进程的内存空间,是隔离的。(空间上的复用)
第四代计算机:个人计算机
多道技术:
产生背景:针对单核,实现并发。
空间复用:内存空间是隔离的
时间复用:遇到I/O就切,提高效率
遇到运行时间过长,不提高效率
并发与并行
并发:伪并行,单个CPU+多道技术,看起来像同时运行。
并行:多个CPU才能实现并行
windows和linux创建进程:
windows: createprocess创建进程的接口
linux: fork创建进程的接口
创建子进程:
linux:子进程是父进程的完整副本,
windows:父进程与子进程的内存地址有所不同
进程状态:
运行
阻塞:碰到I/O,便要让出CPU让其他进程执行,保证CPU一直在工作。
就绪:时刻准备着运行
开启进程的两种方式:
为什么开启子进程就实现了并发?
开启子进程就为了执行自己的任务,而不会因为父进程阻塞,而影响自己。
开启子进程的第一种方法:
from multiprocessing import Process
import time,random def piao (name): print('%s is piaoing' %name) # time.sleep(3000) if __name__ == '__main__': # p=Process(target=piao,args=('alex',)) p=Process(target=piao,kwargs={'name':'alex'}) p.start() #向操作系统发送开启子进程的信号 # p.join() print ('主进程')
结果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九课并发编程/开启子进程.py
主进程
alex is piaoing
结论:
p.start() 只是向操作系统发出一个开启子进程的信号,而不是真正的开启子进程。
当p.start()执行完以后,会立刻执行下一行代码,也就是print(),而不是等待子进程执行后,再执行print().
p.start()只能执行一次,多次会有报错。
上面的例子:如果我想要子进程执行完毕以后,再执行print(),如何实现?
子进程执行完,再执行主进程的代码。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) # time.sleep(3000) if __name__ == '__main__': # p=Process(target=piao,args=('alex',)) p=Process(target=piao,kwargs={'name':'alex'}) p.start() #向操作系统发送开启子进程的信号 p.join() print ('主进程')
结果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九课并发编程/开启子进程.py
alex is piaoing
主进程
结论:在p.start()后面添加一个p.join(),主进程就会在当前位置停下,等待子进程运行完成,再执行后面的代码。p.join()必须在p.start()的后面,否则子进程还未开启,p.join()也没有意义。这么做的意义就是为了防止主进程突然关闭,而导致子进程执行完毕以后,成为了僵尸进程。
开启子进程的第二种方法:
采用自定义类的方式。
from multiprocessing import Process import time,random class Myprocess(Process): def __init__(self,name): super(Myprocess,self).__init__() self.name=name def run(self): print ('%s is piaoing' %self.name) if __name__ == '__main__': p=Myprocess('alex') p.start() print('主')
套接字通信开启子进程
服务端:
from socket import socket from multiprocessing import Process def tongxin(conn,addr): while True: try: cmd = conn.recv(1024) # 收消息,限制单个消息的最大数为1024字节 if not cmd: break conn.send(cmd.upper()) except ConnectionResetError: break conn.close() def lianjie(): s = socket() s.bind(('127.0.0.1', 8080)) # 插卡,指定服务器的IP地址和端口号 s.listen(5) while True: conn, client_addr = s.accept() p=Process(target=tongxin,args=(conn,client_addr)) p.start() s.close() if __name__ == '__main__': lianjie()
客户端:
import socket client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) #打电话 while True: cmd=input('数据>>').strip() if not cmd:continue client.send(cmd.encode('utf-8')) #发消息 recv=client.recv(1024).decode('gbk') #收消息 print(recv) client.close()
进程对象的其他方法:
join方法:
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print ('主进程')
结果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九课并发编程/进程的其他对象方法.py
egon is piaoing
alex is piaoing
wupaiqi is piaoing
主进程
结论:
三个start()都是随机开启的,不会按顺序启动的。
三个join要放在三个start的后面,这样才是并发。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() # p1.join() # p2.join() # p3.join() print ('主进程')
结果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九课并发编程/进程的其他对象方法.py
alex is piaoing
egon is piaoing
wupaiqi is piaoing
主进程
结论:
如果是这么写的,就是真正的串行。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p_l=[p1,p2,p3] for p in p_l: p.start() for p in p_l: p.join() print ('主进程')
进程之间的内存空间是隔离的
from multiprocessing import Process n=100 def task(): global n n=0 print (n) if __name__ == '__main__': p=Process(target=task) p.start() p.join() print('主',n)
结果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九课并发编程/进程之间的内存空间是隔离的.py
0
主 100
结论:
进程之间的内存空间是隔离的,因为我修改了子进程的n,但是主进程的n还是原来的。
查看进程的pid和ppid。
杀死进程
进程池