并发编程.多道技术,进程理论、如何创建进程
2022/1/14 7:05:49
本文主要是介绍并发编程.多道技术,进程理论、如何创建进程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、UDP代码编写(了解)
-
udp是无链接的,先启动哪一端都不会报错
import socket udp_sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议 udp_sk.bind(('127.0.0.1',9000)) # 绑定地址 msg,addr = udp_sk.recvfrom(1024) udp_sk.sendto(b'hi',addr) udp_sk.close() import socket ip_port=('127.0.0.1',9000) udp_sk=socket.socket(type=socket.SOCK_DGRAM) udp_sk.sendto(b'hello',ip_port) back_msg,addr=udp_sk.recvfrom(1024) print(back_msg.decode('utf-8'),addr) """ 时间服务器的实现原理 1.内部小电容供电 2.远程时间同步 """
TCP协议与UDP协议的区别
- UDP的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendinto(y),收完了x个字节的数据就算完成,若是y>x数据就丢失,这意味着udp根本不会粘包,但是会丢数据,不可靠
- TCP的协议数据不会丢,没有收完包,下次接收,会继续上次继续接收,己端总是在收到ack时才会清除缓冲区内容。数据是可靠的,但是会粘包。
二、操作系统的发展史(了解)
"""学习并发编程其实就是在学习操作系统的发展史(底层逻辑)""" 1.穿孔卡片时代 CPU的利用率极低 2.联机批处理系统 将多个程序员的程序一次性录入磁带中 之后交由输入机输入并由CPU执行 3.脱机批处理系统 现代计算机的雏形(远程输入 高速磁带 主机)
三、多道技术
-
并发:是伪并行,多个任务看起来是同时运行。单个cpu+多道技术就可以实现并发,(并行也属于并发)
-
并行:多个任务真正意义上的同时运行,只有具备多个cpu才能实现并行
-
串行:一个任务运行完毕后才能开启下一个任务然后运行
# 前提:单核CPU 多道技术 切换+保存状态 """ CPU工作机制 1.当某个程序进入IO状态的时候 操作系统会自动剥夺该程序的CPU执行权限 2.当某个程序长时间占用CPU的时候 操作系统也会剥夺该程序的CPU执行权限 """ 并行与并发(******) 并行:多个程序同时执行 并发:多个程序只要看起来像同时运行即可 # 问:单核CPU能否实现并行 肯定不能,但是可以实现并发 # 问:12306可以同一时间支持几个亿的用户买票 问是并行还是并发 肯定是并发(高并发) 星轨:微博能够支持八个星轨
-
下面这个图可以看出单cpu运行轨迹
四、进程理论
-
先来先服务调度算法FCFS:按作业或者进程到达的先后顺序依次调度;(平均周转时间可能会很长 )
-
短作业优先调度算法SJF:算法从就绪队列中选择估计时间最短的作业进行处理,直到得出结果或者无法继续执行(周转时间短,但是响应时间长 )
-
高相应比算法HRN:响应比=(等待时间+要求服务时间)/要求服务时间;
-
时间片轮转调度RR:按到达的先后对进程放入队列中,然后给队首进程分配CPU时间片,时间片用完之后计时器发出中断,暂停当前进程并将其放到队列尾部,循环 ;(响应时间可以得到保证)
-
多级反馈队列调度算法:目前公认较好的调度算法;设置多个就绪队列并为每个队列设置不同的优先级,第一个队列优先级最高,其余依次递减。优先级越高的队列分配的时间片越短,进程到达之后按FCFS放入第一个队列,如果调度执行后没有完成,那么放到第二个队列尾部等待调度,如果第二次调度仍然没有完成,放入第三队列尾部…。只有当前一个队列为空的时候才会去调度下一个队列的进程。
# 进程与程序的区别 程序:一堆代码(死的) 进程:正在运行的程序(活的) # 单核情况下的进程调度 进程调度算法演变 1.FCFS 先来先服务 对短作业不友好 2.短作业优先调度算法 对长作业不友好 3.时间片轮转法+多级反馈队列 先分配给新的多个进程相同的时间片 之后根据进程消耗的时间片多少分类别...... # 进程三状态图(******) 就绪态 运行态 阻塞态 进程要想进入运行态必须先经过就绪态 # 同步与异步(******) '''用于描述任务的提交方式''' 同步:提交完任务之后原地等待任务的返回结果 期间不做任何事 异步:提交完任务之后不原地等待任务的返回结果 直接去做其他事 结果由反馈机制自动提醒 # 阻塞与非阻塞(******) '''用于描述任务的执行状态''' 阻塞:阻塞态 非阻塞:就绪态 运行态
五、创建进程
注意:在windows中Process()必须放到# if *name* == '*main*':下
开启进程的方式一:可以让多个任务并发起来在后台同时运行
# 代码层面创建进程 from multiprocessing import Process import time import os def test(name): print(os.getpid()) # 获取进程号 print(os.getppid()) # 获取父进程号 print('%s正在运行' % name) time.sleep(3) print('%s已经结束' % name) if __name__ == '__main__': p = Process(target=test, args=('jason',)) # 生成一个进程对象 p.start() # 告诉操作系统开设一个新的进程 异步提交 print(os.getpid()) print('主') """ 在windows中开设进程类似于导入模块 从上往下再次执行代码 一定需要在__main__判断语句内执行开设进程的代码 在linux中是直接将代码完整的复制一份执行 不需要在__main__判断语句内执行 """ class MyProcess(Process): def __init__(self, name): super().__init__() self.name = name def run(self): print('%s正在运行' % self.name) time.sleep(3) print('%s已经结束' % self.name) if __name__ == '__main__': p = MyProcess('jason') p.start() print('主')
六、进程的join方法
-
加上join并不是变成串行了,而是看join放在什么位置,join往后放看到的是并发
from multiprocessing import Process import time def test(name, n): print('%s is running' % name) time.sleep(n) print('%s is over' % name) if __name__ == '__main__': p_list = [] start_time = time.time() for i in range(1, 4): p = Process(target=test, args=(i, i)) p.start() p_list.append(p) # p.join() # 串行 9s+ for p in p_list: p.join() print(time.time() - start_time) # p = Process(target=test, args=('jason',)) # p1 = Process(target=test, args=('kevin',)) # p2 = Process(target=test, args=('oscar',)) # p.start() # p1.start() # p2.start() print('主进程')
七、进程间默认无法交互
# 进程间数据是相互隔离的 from multiprocessing import Process money = 100 def test(): global money money = 999 if __name__ == '__main__': p = Process(target=test) p.start() # 先确保子进程运行完毕了 再打印 p.join() print(money)
八、对象方法
""" 1.current_process查看进程号 2.os.getpid() 查看进程号 os.getppid() 查看父进程进程号 3.进程的名字,p.name直接默认就有,也可以在实例化进程对象的时候通过关键字形式传入name='' 3.p.terminate() 杀死子进程 4.p.is_alive() 判断进程是否存活 3,4结合看不出结果,因为操作系统需要反应时间。主进程 睡0.1即可看出效果 """
ps:进程对象代码实现方法
# 例1: from multiprocessing import Process import os import time count = 100 def task(): global count count = 0 if __name__ == '__main__': p = Process(target=task) p.start() # 通知操作系统开启进程 p.join() # 主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态) print("主",count) # 例2: from multiprocessing import Process import os import time def task(n): print(os.getpid()) time.sleep(n) if __name__ == '__main__': p1 = Process(target=task,args=(3,)) p2 = Process(target=task,args=(2,)) p3 = Process(target=task,args=(1,)) start = time.time() p1.start() # 通知操作系统开启进程 p1.join() p2.start() # 通知操作系统开启进程 p2.join() p3.start() # 通知操作系统开启进程 p3.join() stop = time.time() print(stop - start) # 加上join并不是变成串行了,而是看join放在什么位置,join往后放看到的是并发 # 例3: from multiprocessing import Process import os import time def task(n): print(os.getpid()) time.sleep(n) if __name__ == '__main__': p1 = Process(target=task, args=(3,),name='进程1') p1.start() print(p1.name,p1.pid) # p1.join() p1.terminate() time.sleep(0.01) print(p1.is_alive())
这篇关于并发编程.多道技术,进程理论、如何创建进程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
- 2024-11-24细说敏捷:敏捷四会之每日站会
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解