操作系统的历史
多道操作系统
遇到io操作就切换
提高cpu利用率
进程之间数据隔离
时空复用: 在同一个时间点上,多个程序同时执行着,一块内存条存了多个进程的数据
分时操作系统
时间分片
时间片轮转
进程
是计算机中最小的资源分配单位, 么一个程序运行起来的时候需要分配一些内存
一个运行的程序
在操作系统中用pid 来唯一标识一个进程
线程
是计算机中能被cpu 调用的最小单位 实际执行具体编译器 之后的代码是线程,所以cpu 执行的是解释之后的线程中的代码
并行个并发
并行(好): 多个cpu 各自在自己的cpu上执行多个程序
并发:一个cpu 多个程序 轮流执行
同步和异步
同步:调用一个操作 要等待结果
异步: 调用一个程序. 不等待结果
阻塞和非阻塞
阻塞:cpu 不工作
非阻塞: cpu 工作
同步阻塞
input sleep recv recvfrom
同步非阻塞
ret =eval('1+2+1+3+3+5')
异步非阻塞-blocking
没讲完
import socket
sk=socket.socket()
sk.setblocking(False)
sk.bind(('127.0.0.1',9001))
sk.listen()
# sk.accept()
#
while 1:
try:
conn,addr=sk.accept()
print(addr)
except BlockingIOError:
pass
这个只是 非阻塞
进程的三状态图
就绪 运行 阻塞
点击运行
|
操作系统接收到指令分配给进程 创建对应的进程id
|
就绪
| \
运行--阻塞
进程的调度算法
给所有的进程分配资源 或者 分配cpu使用权的一种方法
短作业优先
先来先服务
多级反馈算法
- 多个任务队列,优先级从高到低
- 新来的人物, 总是优先级最高
- 每一个新任务 几乎会立即获得一个时间片时间
- 执行完一个时间片之后就会降到下一级队列中]
- 总是优先级高执行完之后才执行优先级低的任务
- 并且优先级越高 时间片越短
进程的开启与关闭
multiprocessing
multi ple 多元化的
processing 进程
multiprocessing 多元的处理进程的模块
from multiprocessing import Process
import os
def func():
print(os.getpid(),os.getppid())
print(1)
#(os.getpid() 我的id ,os.getppid() 父进程 id) #子进程
if __name__ =='__main__':
print(os.getpid(), os.getppid()) #主进程
# #第一种 调用种方式
p=Process(target=func) #第二种调用方式
p.start() #不知道为什么运行不了
原因是 不能再ide 中运行
在命令行 中 可以运行
#父进程 子进程 数据隔离
传参数
p=Process(target=func,arges('小白',) #arges 这里是传参数
p.start()
例子2
from multiprocessing import Process
def func(name):
print('hello', name)
def main():
p = Process(target=func, args=('bob',))
p.start()
# p.join()
if __name__ == '__main__':
main()
#传了name参数 打印出来 hello,bob
异步非阻塞 是个什么样子
if __name__ == '__main__':
main()
print("完了")
main()
main()
main()
#完了
#hello bob
#hello bob
#hello bob
#hello bob
#这就是 异步非阻塞 同时运行
有个缺点: 就是 上面执行不完 的时候
最后一个已经打印出来了
这个不合适
这个时候 上面的程序还没运行完呢
是一个欺骗行为 是不允许的
加一个 p.join()
from multiprocessing import Process
def func(name):
print('hello', name)
def main():
p = Process(target=func, args=('bob',))
p.start()
p.join()
if __name__ == '__main__':
main()
main()
main()
main()
print("晚了")
#hello bob
#hello bob
#hello bob
#hello bob
#晚了
正常顺序
这就是 join的妙用
p.join() 正确使用方式
from multiprocessing import Process
import time
import random
def func(name,age):
print(f'发送一封邮件给{age}岁的{name}')
time.sleep(random.random())
print('发送完毕')
join
from multiprocessing import Process
import time
import random
def func(name, age):
print(f'发送一封邮件给{age}岁的{name}')
time.sleep(random.random())
print('发送完毕')
if __name__=='__main__':
lst=[('太白',40),('小白',30)]
p_lst=[]
for i in lst:
p = Process(target=func, args=i)
p.start()
p_lst.append(p)
for p in p_lst:
p.join()
不要求并行的顺序的时候
就全部 运行之后 然后在开启join
要求运行顺序的时候 就
运行一个 join 一个
# p=Process(target=func,args=('太白',"40"))
# p.start()
# p = Process(target=func, args=('太白', "40"))
# p.start()
# p = Process(target=func, args=('太白', "40"))
# p.start()
# p = Process(target=func, args=('太白', "40"))
# p.start()
# p.join()
print('全部发送完了')
为什么要用 _ name_ == "_ _ main_"
能不能给子进程 传递 函数
能不能获取子进程的返回值
能不能同时开启多个子进程
join的用法
同步阻塞 异步非阻塞
同步阻塞: join()
异步非阻塞: start()
socket实现 创建子进程 实现并行链接
import socket
from multiprocessing import Process
def talk(conn):
while 1:
msg=conn.recv(1024).decode('utf-8')
# print(msg)
ret=msg.upper().encode('utf-8')
conn.send(ret)
conn.close()
if __name__=='__main__':
sk=socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
while 1: #这里创建一个子进程 每连一个是一个新的地址
#现在可以随意 连多个主机
conn,addr=sk.accept() #异步非阻塞 还是有点不太理解
Process(target=talk, args=(conn,)).start()
sk.close
# Process(target=talk,args=(sk,)).start()
# Process(target=talk,args=(sk,)).start() 不能这么写 这样可以连接两个主机
中规中矩的客户端
import socket
import time
sk=socket.socket()
sk.connect(('127.0.0.1',9001))
while 1:
sk.send(b'hello')
msg=sk.recv(1024).decode('utf-8')
print(msg)
time.sleep(0.5)
sk.close()