进程的特点
- 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
- 并发性:任何进程都可以同其他进程一起并发执行;
- 独立性:进程是系统进行资源分配和调度的一个独立单位;
- 结构性:进程由程序、数据和进程控制块三部分组成。
子进程不一定依赖于父进程,可以父进程结束了,子进程依然存在。
1.开启多进程
两种方式。
- 方式一:调用函数
- 方式二:继承Process
# 方式一
from multiprocessing import Process
import time
import os
def func(args, args2):
print(args, args2)
time.sleep(1)
print('子进程:', os.getpid())
print('子进程的父进程:', os.getppid())
print('func')
# 开启一个进程
p = Process(target=func, args=('参数一', '参数二')) # register, p is a process object
p.start() # start
print('*'*10)
print('父进程:', os.getpid()) # 查看当前进程的进程号
print('父进程的父进程:', os.getppid()) # 查看当前进程的父进程
# 输出结果:
# **********
# 父进程: 7207
# 父进程的父进程: 1114
# 参数一 参数二
# 子进程: 7208
# 子进程的父进程: 7207
# func
# 方式二:
import os
from multiprocessing import Process
class MyProcess(Process):
def run(self) -> None:
print(self.pid)
print(self.name)
print('子进程的id', os.getpid())
print('主进程的id:', os.getpid())
p1 = MyProcess()
p1.start()
p2 = MyProcess()
p2.start()
# 方式二:(能传参)
# --> 通过 __init__
from multiprocessing import Process
import os
class MyProcess(Process):
def __init__(self, arg1, arg2): # 继承了Process, __init__也要继承父类的__init__
super().__init__()
self.arg1 = arg1
self.arg2 = arg2
def run(self) -> None:
print(self.pid) # 都是在父类Process中init方法中就有的。
print(self.name) # 都是在父类Process中init方法中就有的。
print(self.arg1)
print('主进程的id:', os.getpid())
p1 = MyProcess(1, 3)
p1.start()
2.多进程的join方法
join方法:p.join() 是感知一个子进程的结束,将异步的程序改为同步
from multiprocessing import Process
import os
def func(filename, content):
with open(filename, 'w') as f:
f.write(content)
# 开启十个进程,同时开始写,等待全部写完后,展示文件夹中的所有文件
p_list = []
for i in range(10):
p = Process(target=func, args=('info%s'%i, 'content%s'%i))
p_list.append(p)
p.start()
[p.join() for p in p_list] # 之前的所有进程必须在这里执行完,才会执行下面的代码
print([i for i in os.walk('/Users/yanl/PycharmProjects/FullStack/并发编程')])
3.多进程之间的数据隔离问题
from multiprocessing import Process
import os
def func():
global n
n = 0
print('子进程id:', os.getpid(), 'n=', n)
n = 100
p = Process(target=func)
p.start()
print('n=', n)
输出结果:
n= 100
子进程id: 7490 n= 0
子进程中更改了全局变量,并不能影响父进程中全局变量的值。进程之间的数据,不通过特殊手段是不能互通的。
4.使用多线程实现socket服务端的并发效果
server端
import socket
from multiprocessing import Process
def server(conn):
conn.send(('hello').encode('utf-8'))
msg = conn.recv(1024).decode('utf-8')
print(msg)
conn.close()
sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()
while True:
conn, addr = sk.accept() # 收到一个连接,就开启一个进程。
p = Process(target=server, args=(conn, ))
p.start()
sk.close()
client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
msg = sk.recv(1024).decode('utf-8')
print(msg)
sendmsg = input('>>>').encode('utf-8')
sk.send(sendmsg)
sk.close()
5.守护进程
守护进程会随着主进程的代码
执行完毕而结束。(是主进程的代码 不看其他子进程的执行时间 )
用法:在p.start()
之前添加代码p.daemon=True
from multiprocessing import Process
import time
def func():
while True:
time.sleep(0.2)
print('func 进程还在运行')
p = Process(target=func)
p.daemon = True # 将子进程设置为守护进程
p.start()
i = 0
while i < 5:
print('主进程还在运行')
time.sleep(0.3)
i += 1
运行结果:
主进程还在运行
主进程还在运行
func 进程还在运行
主进程还在运行
主进程还在运行
func 进程还在运行
主进程还在运行
当有多个子进程时,守护进程func在主进程代码执行完毕后马上结束,并不等待其他子进程func2执行完。代码如下:
# 多个子进程
from multiprocessing import Process
import time
def func():
while True:
time.sleep(0.2)
print('func 进程还在运行')
def func2():
time.sleep(6)
print('func2 刚刚执行完')
p = Process(target=func)
p.daemon = True # 将子进程设置为守护进程
p.start()
p2 = Process(target=func2).start()
i = 0
while i < 5:
print('主进程还在运行')
time.sleep(0.3)
i += 1
other
- 进程的方法:
p = Process(target=func)
p.join() # p.join() 是感知一个子进程的结束,将异步的程序改为同步
p.terminate() # 结束该子进程
p.is_alive() # 检查该进程是否还活着。真则返回True
- 进程的属性:
p.name # 返回该进程的名字
p.pid # 返回该进程的进程号
网友评论