#同步和异步
#同步:调用一个操作,等待结果
#异步:调用一个操作,不等待结果
#阻塞和非阻塞
#阻塞:cpu不工作
#非阻塞:cpu工作
#同步阻塞:
#input sleep recv recvfrom
#同步非阻塞
#ret = eval('1+2+3+4')
#异步非阻塞
#进程的三状态图 就绪 运行 阻塞
#进程的调度算法
#给所有的进程分配资源或者分配CPU使用权的一种方法
#短作业优先:
#先来先服务 FCFS:
#多级反馈算法:
# 把每个任务都放到列表中,进程有优先级,永远先执行级别高的列表中的进程,级别低的分的时间片越高,涵盖了 短作业优先 FCFS 和时间片轮转
#多个任务队列,优先级从高到低
#新来的任务总是优先级最高
#每个新任务几乎会立刻获得时间片的时间
#执行完一个时间片之后会降到下一级队列中
#总是优先级高的任务都执行完才执行优先级低的队列
#并且优先级越高时间片越短
#考虑降低阻塞
#进程的开启和关闭
#开启子进程
from multiprocessing import Process
import os
def func():
print(os.getpid(),os.getppid()) #8412 292 #8412是子进程,func就在子进程里执行,292是main主进程
if __name__ == '__main__': #windows上加,mac上可以不用加
print('main:',os.getpid(),os.getppid()) #292 10872 其中292 是 main主进程,10872是pycharm进程
p = Process(target=func)
p.start()
#if __name__ == '__main__':
#进程中的内存是隔离的,开启一个子进程就开辟一个空间,复制父进程里的变量函数过去等
#能不能给子进程传递参数?可以,Process(target=func,args=(a,b,)) 另外args这里是元组,如果是一个参数写成args=(a,)
#能不能获取子进程的返回值?不可以,但是主进程最终要等所有子进程结束,回收子进程资源
#能不能同时开启多个子进程?可以,多次实例化Process 并启动start() ,start()方法会调用Process类里的run方法
#join的用法
#同步阻塞,异步非阻塞
#使用多进程实现一个并发的socket的server
#传参
import time
from multiprocessing import Process
def f(name):
print('hello',name)
time.sleep(1)
print('子进程')
if __name__ == '__main__':
p = Process(target=f,args = ('bob',))
p.start()
print('主进程')
#获取子进程 父进程id
import os
from multiprocessing import Process
def f(x):
print('子进程id:',os.getpid(),'父进程id:',os.getppid())
return x*x
if __name__ == '__main__':
print('主进程id:',os.getpid())
p_list = []
for i in range(5):
p = Process(target=f,args=(i,))
p.start()
# 主进程id: 7616
# 子进程id: 9336 父进程id: 7616
# 子进程id: 8924 父进程id: 7616
# 子进程id: 3812 父进程id: 7616
# 子进程id: 5088 父进程id: 7616
# 子进程id: 10204 父进程id: 7616
#多个进程同时运行
import time
from multiprocessing import Process
def f(name):
print('hello',name)
time.sleep(1)
if __name__ == '__main__':
p_list = []
for i in range(5):
p = Process(target=f,args=('bob',))
p.start()
p_list.append(p) #把进程添加到了列表里
#多进程同时运行,join方法,子进程等父进程结束再执行自己的代码
import time
from multiprocessing import Process
def f(name):
print('hello,',name)
time.sleep(1)
if __name__ == '__main__':
p_list = []
for i in range(5):
p = Process(target=f,args=('bob',))
p.start()
p_list.append(p)
p.join() # 子进程执行了join,父进程就等子进程执行结束再执行,这里循环创建了5个子进程
print('父进程在执行')
# hello, bob
# hello, bob
# hello, bob
# hello, bob
# hello, bob
# 父进程在执行
#继承Process类
import os
from multiprocessing import Process
class MyProcess(Process):
def __init__(self,name):
super().__init__() #执行父类中的init
self.name = name
def run(self):
print(f'{self.name},正在通话')
if __name__ == '__main__':
p1 = MyProcess('tom')
p2 = MyProcess('jerry')
p3 = MyProcess('lucy')
p1.start() #start 会自动调用 MyProcess 的run方法
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print('主进程')
# tom, 正在通话
# jerry, 正在通话
# lucy, 正在通话
# 主进程
#进程之间数据隔离
def f1():
global n #设置n为全局变量
n=200
print('在f1里n=',n)
def f2():
print('在f2里n=',n)
f1() #在f1里n= 200
f2() #在f2里n= 200
#进程之间的数据隔离
from multiprocessing import Process
def f():
global n
n = 0
print('子进程n=',n)
if __name__ == '__main__':
n=100 #n是主进程变量,在子进程里设置成了global全局,结果
p = Process(target=f)
p.start()
print('主进程内n=',n)
# 主进程内n= 100
# 子进程n= 0
#守护进程 p.daemon = True,父进程代码执行结束之前,守护进程结束
import os
import time
from multiprocessing import Process
class Myprocess(Process):
def __init__(self,person):
super().__init__()
self.person = person
def run(self):
print(os.getpid(),self.name)
print('%s正在通话' %self.person)
if __name__ == '__main__':
p = Myprocess('tom')
p.daemon = True # 在p.start()之前设置 进程daemon 属性是True 如果主进程终止,守护进程p也终止
p.start()
time.sleep(5) # 在sleep时查看进程id对应的进程ps -ef|grep id
print('主进程')
# 7964 Myprocess-1
#tom正在通话
#主进程
#主进程代码结束,守护进程立即结束
import time
from multiprocessing import Process
def f1():
print('f1')
time.sleep(1)
print('f1 end')
def f2():
print('f2')
time.sleep(3)
print('f2 end')
if __name__ == '__main__':
print('主进程开始')
p1 = Process(target=f1)
p2 = Process(target=f2)
p1.daemon = True #p1被设置成守护进程,随着主进程代码执行结束而结束
p1.start()
p2.start()
time.sleep(0.5)
#当这里时间设置成0.1 ,p1都没轮到执行就结束了,但是p2先打印f2再打印f2 end,才结束,后于主进程结束
#当这里时间设置成0.5,p2进程里的f2 完全打印,但是p1进程里的f1函数只打印了第一句 f1,后面f1 end 还没来得及打印就结束了
print('主进程结束')
#用进程实现socket 聊天
#server端
from socket import *
from multiprocessing import Process
sk = socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#啥意思 SOL_SOCKET SO_REUSEADDR
#上面用import socket的方式引用,SOL_SOCKET这些参数就识别不出来,报错
sk.bind(('127.0.0.1',9001))
sk.listen(5) #最多连接5个? 并没有,尝试了6个也行
def talk(conn,client_addr): #方法把建立后的连接,接收到的小写字母转化成大写并发送回去
while True:
try:
msg = conn.recv(1024)
if not msg :break
conn.send(msg.upper())
except Exception:
break
conn.close()
if __name__ == '__main__':
while True:
conn,client_addr = sk.accept()
p = Process(target=talk,args=(conn,client_addr)) #这里把conn 这个连接对象当做参数放到子进程中,是否可以把sk当做参数写进子进程
p.start()
#子进程的创建,target对应的都是函数?
#client端
from socket import *
sk = socket()
sk.connect(('127.0.0.1',9001))
while True:#无限循环 实现持续聊天
msg = input('>>>').strip()
if not msg:continue
sk.send(msg.encode('utf-8'))
msg = sk.recv(1024)
print(msg.decode('utf-8'))
#进程中terminate方法和 is_alive方法
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
self.name = name
super().__init__() #调用父类的init函数
def run(self): #p子进程start 以后 自动调用进程中run方法
print('子进程运行中。。。')
time.sleep(1)
print('子进程结束')
if __name__ == '__main__':
p1 = MyProcess('tom')
p1.start()
p1.terminate()
print(p1.is_alive()) #打印子进程p1的状态为True
#虽然上面把p1进程terminate终止了,但是结果显示进程还在,不会立即结束
#Process 的pid方法 和 name属性
from multiprocessing import Process
class MyProcess(Process):
def __init__(self,name):
self.name = name #这里的name属性是Process里的特有属性,表示进程的名字
super().__init__()
def run(self):
print(f'{self.name}')
#分别打印 MyProcess-1 和 MyProcess-2
if __name__ == '__main__':
p1 = MyProcess('tom')
p2 = MyProcess('tom')
p1.start()
p2.start() # print(p1.pid) #7716 还可以用os.getpid() 获取进程id
#多个进程抢占输出资源
import os
import time
import random
from multiprocessing import Process
def f(n):
print(f'{n},{os.getpid()} running')
time.sleep(random.random()) #这里如果不增加sleep随机数,0,1,2这三个子进程顺序执行,如果增加,输出会错乱,有可能1进程的close 会在2进程的running之后输出
print(f'{n},{os.getpid()} close')
if __name__ == '__main__':
for i in range(3):
p = Process(target=f,args=(i,))
p.start()
#使用进程锁
import os
import time
import random
from multiprocessing import Process,Lock
def f(n,lock1):
lock1.acquire()
print(f'{n},{os.getpid()} running')
time.sleep(random.random())
print(f'{n},{os.getpid()} close')
lock1.release()
if __name__ == '__main__':
lock1 = Lock()
lock1.release()
for i in range(3):
p = Process(target=f,args=(i,lock1))
p.start()