网络编程(四)

网络编程(四)


昨日内容


UDP协议


import socket  # 服务端 server = socket.socket(type=socket.SOCK_DGRAM)  # 自己指定UDP协议(默认是TCP协议) server.bind(('127.0.0.1', 8080))  # 和TCP几乎一样,写入地址和端口号 msg, addr = server.recvfrom(1024)  # 待接收 print('msg:', msg.decode('utf8')) print('addr:', addr)  # 额外打印出端口号,为了确定是哪个客户端 server.sendto(b'hello baby', addr)   import socket  # 客户端 client = socket.socket(type=socket.SOCK_DGRAM)  # 自己指定UDP协议(默认是TCP协议) server_addr = ('127.0.0.1', 8080)  # 查找通讯录 client.sendto(b'hello server baby', server_addr) msg, addr = client.recvfrom(1024) print('msg:', msg.decode('utf8')) print('addr:', addr)  不同处 	UDP																		 		TCP socket.socket(type=socket.SOCK_DGRAM)				socket.socket() recvfrom()																	recv() sendto()																		send() 

操作系统发展史


graph TB 无操作系统-->联机批处理-->脱机批处理

一句话概括操作系统发展史:为了最大的提升CPU的利用率


多道技术

IO操作:IO操作中的读写操作不是我们平时所说读写看,而是将数据加载到硬盘中,我们叫IO流的写操作,即输入流,将硬盘加载出来,叫做IO流的读操作,即输出流。

串行:多个程序依次执行

多道:利用IO操作的间隙:看似多个程序同时执行


进程理论

程序:代码集合体

进程:正在执行的代码集合体

时间片轮转、优先级、多级反馈队列:

这篇博客描述的很好:调度算法——时间片轮转、优先级、多级反馈队列(例题详细!!!)


并发与并行

'''描述的是任务的的工作方式'''

并发:看上去像同时在执行就可以称之为是并发(单个CPU就可以)

并行:必须同一时间同时执行(必须要有多个CPU才可以)

高并发量:1星轨,2星轨······


同步与异步

'''描述的是任务的提交方式'''

同步:提交完任务之后原地等待任务的结果 期间不做任何事(类似串行)

异步: 提交完任务之后不原地等待结果 结果通过反馈机制获取 (类似多道)


阻塞与非阻塞

'''描述的是任务的执行状态'''

阻塞:阻塞态

非阻塞:就绪态 运行态



今日学习内容


代码创建进程

第一种: from multiprocessing import Process import time   def task(name):     print('%s is running' % name)     time.sleep(3)     print('%s is over' % name)   if __name__ == '__main__':     p = Process(target=task, args=('eason',))  # 创建一个进程对象     p.start()  # 告诉操作系统创建一个新的进程并启动进程中的所有功能     print('主进程')    强调:不同的操作系统创建进程的要求不一样     在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中     否则会直接报错 因为在无限制创建进程     在linux和mac中创建进程是直接拷贝一份源代码然后执行 不需要写在__main__子代码中  第二种: from multiprocessing import Process import time class MyProcess(Process):     def __init__(self, username):  # 重写__init__方法         self.username = username  # 新增一个参数         super().__init__()  # 重新调用原始方法     def run(self):         print('我是',self.username)         time.sleep(3)         print('我也是',self.username) if __name__ == '__main__':     p = MyProcess('eason')     p.start()     print('主进程') 

进程实现并发

'''服务端''' import socket from multiprocessing import Process  server = socket.socket() server.bind(('127.0.0.1', 8080)) server.listen(5)  # 将服务客户端的代码封装成函数(通信代码) def talk(sock):     while True:         data = sock.recv(1024)         print(data.decode('utf8'))         sock.send(data.upper())  if __name__ == '__main__':     while True:         sock, addr = server.accept()         p = Process(target=talk, args=(sock, ))         p.start()  '''客户端''' import socket  client = socket.socket() client.connect(('127.0.0.1', 8080))  while True:     client.send(b'多个客户端不同的消息')     data = client.recv(1024)     print(data.decode('utf8')) 

join方法

from multiprocessing import Process import time   def task(name, n):     print(f'{name} is running')     time.sleep(n)     print(f'{name} is over')   if __name__ == '__main__':     p1 = Process(target=task, args=('jason', 1))     p2 = Process(target=task, args=('tony', 2))     p3 = Process(target=task, args=('kevin', 3))     start_time = time.time()     p1.start()  # 调用一个工作一秒的对象     p2.start()	# 调用一个工作两秒的对象     p3.start()	# 调用一个工作三秒的对象     p1.join()	# 结束一个工作进程     p2.join()	# 结束一个工作进程     p3.join()	# 结束一个工作进程     end_time = time.time() - start_time  # 计算三个进程都工作完的时间     print('主进程', f'总耗时:{end_time}')  # 主进程 总耗时:三秒     因为三个工作进程是并发启动的,总共用时取决于时间最长的那个      注意:       	如果是一个start一个join交替执行 那么总耗时就是各个任务耗时总和     因为每项工作执行完后才会继续下一项工作 

进程间数据默认隔离

# 内存可以看成是有很多个小隔间组成的 彼此不干扰 from multiprocessing import Process  money = 999  def task():     global money  # 局部修改全局不可变类型     money = 666  if __name__ == '__main__':     p = Process(target=task)     p.start()     p.join()  # 确保子进程代码运行结束再打印money     print(money)   默认隔离  但是可以通过一些技术打破 

进程对象属性

1.查看进程号的方法 	1.1.current_process函数   	from multiprocessing import Process, current_process     current_process().pid  	# 获取进程号的用处之一就是可以通过代码的方式管理进程   	windows  			taskkill关键字     mac/linux  		kill关键字   1.2.os模块   	os.getpid()  # 获取当前进程的进程号     os.getppid()  # 获取当前进程的父进程号 2.杀死子进程 	terminate() 3.判断子进程是否存活 	is_alive() 

僵尸进程与孤儿进程

僵尸进程:终止主进程时,主进程会默认等待子进程结束才会结束

所有子进程在运行结束之后就会变成僵尸进程,因为没有主进程去接受这个子进程了

这写子进程短时间保留着pid和一些运行过程的中的记录便于主进程查看

这些信息会被主进程回收

  1. 主进程正常结束
  2. 调用join方法

孤儿进程:子进程存活着 父进程意外死亡,子进程会被系统自动接管


亚索路过~


守护进程

 守护即死活全部参考守护的对象 	对象死立刻死  from multiprocessing import Process import time   def task(name):     print(f'主进程{name}启动')     time.sleep(3)     print(f'主进程{name}结束了')  if __name__ == '__main__':     p = Process(target=task, args=('子进程',))     # 必须写在start前面     # p.daemon = True  # 将子进程设置为守护进程:主进程结束 子进程立刻结束     p.start()     print('主进程结束了')      结果: 主进程结束了 主进程子进程启动 主进程子进程结束了 主进程被结束但是子进程还是继续运行到结束  from multiprocessing import Process import time	   def task(name):     print(f'主进程{name}启动')     time.sleep(3)     print(f'主进程{name}结束了')  if __name__ == '__main__':     p = Process(target=task, args=('子进程',))     # 必须写在start前面     p.daemon = True  # 将子进程设置为守护进程:主进程结束 子进程立刻结束     p.start()     print('主进程结束了')      结果: 主进程结束了  主进程被杀死 

互斥锁

from multiprocessing import Process, Lock mutex = Lock() mutex.acquire()  # 抢锁 mutex.release()  # 放锁  针对互斥锁