文章目录
- 一、socketserver模块
- 1.服务端
- 2.客户端1
- 3.客户端2
- 4.效果截图
- 二、一些重要知识
- 三、创建进程的两种方式和join方法
- 1.非程序方面开启进程
- 2.程序层面开启进程
- 3.join方法
- 四、进程间数据隔离
- 五、进程对象及其他方法
- 六、僵尸进程、孤儿进程、守护进程
- 七、互斥锁
- 八、队列&消息队列、IPC机制
- 九、生产者消费者模型
一、socketserver模块
- 该模块用于在网络编程中实现并发效果
- 下面模拟一个客户输入信息然后服务端返回信息大写的并发效果
1.服务端
import socketserver
#基于tcp协议
'''
self.request=>conn
'''
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
print(self.client_address)
while True:
try:
msg = self.requset.recv(1024)
if len(msg) == 0: break
self.request.send(msg.upper())
except Exception:
break
self.request.close()
#服务端应该做两件事情
#第一件事:循环地从半链接池中取出链接 请求与其建立双向链接
#第二件事:拿到链接对象,与其进行通信循环
s=socketserver.TCPServer(('127.0.0.1',8880),MyRequestHandle)
s.serve_forever()
2.客户端1
import socket
client = socket(AF_INET,SOCK_STREAM)
cliene.connect(('127.0.0.1',8880))
while True:
msg = input('请输入命令:').strip()
if len(msg) == 0: continue
client.send(msg.encode('utf-8'))
res = client.rece(1024)
print(res.decode('utf-8'))
3.客户端2
import socket
client = socket(AF_INET,SOCK_STREAM)
cliene.connect(('127.0.0.1',8880))
while True:
msg = input('请输入命令:').strip()
if len(msg) == 0: continue
client.send(msg.encode('utf-8'))
res = client.rece(1024)
print(res.decode('utf-8'))
4.效果截图
二、一些重要知识
- 操作系统的发展历史是围绕提高CPU运行效率展开的
- 进程:正在运行的程序
- 程序:代码
- 多道技术:
- 目的:单核实现并发
- 主要是实现程序对计算机的空间复用和时间复用
- 空间复用:多个程序共用一计算机硬件系统
- 时间复用:保存程序的运行状态+切换程序
+切换分为两种情况:
1.程序遇到IO操作
2.程序运行时间过长
- 并行和并发
- 并发:看起来像同时在做不同事情
- 并行:同时做不同的事情
- 进程的调度
- 先来先服务调度算法
- 短作业优先调度算法
- 时间片轮转法+多级反馈队列
- 进程三状态
+就绪态、运行态、阻塞态
+程序要进入运行态前必然经历就绪态
+阻塞态就是遇到IO等操作会进入阻塞态 - 同步&异步、阻塞&非阻塞
- 同步异步是针对任务提交而言
- 阻塞非阻塞是针对程序运行状态而言
- 效率最高的就是异步非阻塞
三、创建进程的两种方式和join方法
1.非程序方面开启进程
随便双击几个应用,几个应用同时运行就是开了多个进程
2.程序层面开启进程
创建进程的两种方式 第一种应用颇多
3.join方法
- 简单来说就是让主进程等着子进程运行完之后,主程序再往下运行
- 我们来做一个程序时间测试的小程序
from multiprocessing import Process
import time
def task(i):
time.sleep(i)
if __name__ == '__main__':
pro_lis = []
start = time.time()
# 创建三个进程
for i in range(3):
p = Process(target=task,args=(i,))
pro_lis.append(p)
# 启动三个进程
for pro in pro_lis:
pro.start()
print(time.time()-start)
运行结果:0.0258924961090087
尽管这并不是程序最终运行时间,实际上时间应该是2s多,但结合下面例子你足以看出join的用法,有点并发变串行的感觉。
from multiprocessing import Process
import time
def task(i):
time.sleep(i)
if __name__ == '__main__':
pro_lis = []
start = time.time()
# 创建三个进程
for i in range(3):
p = Process(target=task,args=(i,))
pro_lis.append(p)
# 启动三个进程
for pro in pro_lis:
pro.start()
pro.join()
print(time.time()-start)
结果:4.735849142074585
四、进程间数据隔离
- 这是一个结论,我们来验证一下
from multiprocessing import Process
money = 100
def task():
global money # 局部修改全局
money = 666
print('子',money)
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print(money)
Result:
子 666
100
五、进程对象及其他方法
- p.terminate() # 杀死当前进程
- p.is_alive() # 判断当前进程是否存活
- os.getpid() 获得进程号 等同于current_process().pid
- 补充:Windows:cmd里 tasklist查看所有进程
- tasklist | find “关键字” 可以对结果进行过滤,即单独获取某个程序的进程
+os.getppid() #获得父进程号
from multiprocessing import Process, current_process
import time
import os
def task():
print('%s is running'%current_process().pid) # 查看当前进程的进程号
print('%s is running'%os.getpid()) # 查看当前进程的进程号
print('子进程的主进程号%s'%os.getppid()) # 查看当前进程的进程号
time.sleep(30)
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.terminate() # 杀死当前进程
# 是告诉操作系统帮你去杀死当前进程 但是需要一定的时间 而代码的运行速度极快
time.sleep(0.1)
print(p.is_alive()) # 判断当前进程是否存活
"""
一般情况下我们会默认将
存储布尔值的变量名
和返回的结果是布尔值的方法名
都起成以is_开头
"""
print('主')
print('主',current_process().pid)
print('主',os.getpid())
print('主主',os.getppid()) # 获取父进程的pid号
结果:
False
主
主 9256
主 9256
主主 18360
六、僵尸进程、孤儿进程、守护进程
- 僵尸进程指的是该进程结束后没死完,会保留一段时间,供父进程查看这个进程的进程号、运行时间等信息,当父进程存在一直在产生子进程的时候,无限开辟内存空间,这是不好的
- 孤儿进程是子进程存活,而父进程死亡,操作系统有个机制会解决孤儿进程回收问题
- 守护线程是跟着操作系统同生共死的进程
- p.daemon = True # 将进程p设置成守护进程
- 这一句一定要放在start方法上面才有效否则会直接报错
一个例子:古代皇帝驾崩其身边太监也必须gameover
from multiprocessing import Process
import time
def task(name):
print('%s总管正在活着'% name)
time.sleep(3)
print('%s总管正在死亡' % name)
if __name__ == '__main__':
p = Process(target=task,args=('太监',))
# p = Process(target=task,kwargs={'name':'egon'})
p.daemon = True # 将进程p设置成守护进程 这一句一定要放在start方法上面才有效否则会直接报错
p.start()
print('皇帝寿终正寝')
结果:注意太监。。
皇帝寿终正寝
注释守护进程之后
from multiprocessing import Process
import time
def task(name):
print('%s总管正在活着'% name)
time.sleep(3)
print('%s总管正在死亡' % name)
if __name__ == '__main__':
p = Process(target=task,args=('太监',))
# p = Process(target=task,kwargs={'name':'egon'})
# p.daemon = True # 将进程p设置成守护进程 这一句一定要放在start方法上面才有效否则会直接报错
p.start()
print('皇帝寿终正寝')
结果:
皇帝寿终正寝
太监总管正在活着
太监总管正在死亡
七、互斥锁
八、队列&消息队列、IPC机制
九、生产者消费者模型