##
进程是一个执行中的程序,每个进程拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据,所以采用进程间通信的方式共享信息,操作系统管理其上所有进程的执行,并为这些进程合理的分配时间。
创建子进程
进程之间的父子是相对的
import time
import os
# os.getpid()获取当前进程的PID号;
print("主进程%s正在启动....." %(os.getpid()))
# 创建子进程
# 会返回2个值, 一个为0, 一个为非0;
# 子进程永远返回的是0, 父进程返回的是子进程的pid;
# 父进程里面会有很多子进程, 必须记录子进程的pid号;
pid = os.fork()
if pid == 0:
print("这是一个子进程, pid为%d, 父进程的pid为%d" %(os.getpid(), os.getppid()))
else:
print("这个是父进程, 创建了一个子进程, 子进程id为%s" %(pid))
创建多线程
Process用来描述进程对象
import multiprocessing
import os
def work(num):
print('work-%s' %num)
#获取当前进程的名称
print("进程%s 正在运行,pid=%s" %(multiprocessing.current_process().name,
os.getpid()))
print("父进程:%s" %(os.getpid()))
#创建一个列表用来存放子进程对象
jobs=[]
for i in range(4):
name="process%s" %(i)
#实例华一个子进程对象,name表示进程的名字,target表示执行的函数,
# args为函数需要传入的参数以tuple的形式传入
p=multiprocessing.Process(name=name,target=work,args=(i,))
jobs.append(p)
#启动多进程
p.start()
for p in jobs:
#实现所有进程间的同步,等所有子进程结束再执行主进程
p.join()
print("主进程结束,pid=%s,ppid=%s" %(os.getpid(),os.getppid()))
运行结果
父进程:5363
work-0
进程process0 正在运行,pid=5364
work-1
进程process1 正在运行,pid=5365
work-2
进程process2 正在运行,pid=5366
work-3
进程process3 正在运行,pid=5367
主进程结束,pid=5363,ppid=4175
对守护进程的理解
Daemon(守护进程)是运行在后台中的一种特殊进程,独立于控制终端并且周期性的执行某种任务或等待处理某些发生事件。常见的守护进程包括:日志进程syslogd、web服务器httpd、邮件服务器和数据库服务器等。
终止进程
import multiprocessing
import os
import time
# p.terminate()强制终止结束进程, 结束之后通过join方法更新状态;
def work(num):
print('work-%s' %(num))
time.sleep(2)
# 获取当前进程的名称
print("进程%s正在运行, pid=%s" %(multiprocessing.current_process().name,
os.getpid()))
p = multiprocessing.Process(target=work, args=(1,))
print('Before:', p, p.is_alive())
p.start()
print('During:', p , p.is_alive())
# 结束进程的执行;
# p.terminate()
print("正在中之进程:", p, p.is_alive())
p.join()
print("更新状态后:", p, p.is_alive())
运行结果:
派生多进程
class SubProcess(multiprocessing.Process):
def __init__(self, name, num):
super(SubProcess, self).__init__()
self.num = num
def run(self):
print('work-%s' %(self.num))
# 获取当前进程的名称
print("进程%s正在运行, pid=%s" %(multiprocessing.current_process().name,
os.getpid()))
print("父进程:%s" %(os.getpid()))
jobs = []
for i in range(10):
name = "进程%s" %(i)
# 实例化对象, 默认执行类的构造函数.
p = SubProcess(name, i)
jobs.append(p)
p.start()
for job in jobs:
job.join()
print("主进程结束, pid=%s, ppid=%d" %(os.getpid(), os.getppid()))
进程间的通信
import os
from multiprocessing import Queue
from multiprocessing import Process
from random import randint
import time
def write(q):
# 1. python只要是编程, for循环里面不要加运算;
# list = os.listdir("/etc") # ['1', '2', '3']
# for file in os.listdir("/etc"):
# print(file)
n = randint(1,5)
for i in range(n):
if q.full():
print("write full")
else:
q.put(i)
time.sleep(3)
print("队列写入数据%s成功!" %(i))
# 消费者
def read(q):
if q.empty():
print("read none")
else:
n = randint(1,5)
for i in range(n):
value = q.get()
print("队列读取数据%d成功!" %(value))
def main():
import multiprocessing
q = Queue(5)
qw = Process(target=write, args=(q,))
qr = Process(target=read, args=(q,))
qw.start()
qr.start()
print(multiprocessing.active_children())
qw.join()
qr.join()
print("进程间通信结束!")
print("主进程的pid:%s, 父进程的pid为:%s" %(os.getpid(), os.getppid()))
if __name__ == "__main__":
main()
创建进程池
import os
from multiprocessing import Manager
from multiprocessing import Process
from multiprocessing import Pool
from random import randint
import time
def write(q):
# 1. python只要是编程, for循环里面不要加运算;
# list = os.listdir("/etc") # ['1', '2', '3']
# for file in os.listdir("/etc"):
# print(file)
n = randint(1,5)
for i in range(n):
if q.full():
print("write full")
else:
q.put(i)
print("队列写入数据%s成功!" %(i))
time.sleep(1)
# 消费者
def read(q):
if q.empty():
print("read none")
else:
n = randint(1,5)
for i in range(n):
value = q.get()
print("队列读取数据%d成功!" %(value))
time.sleep(1)
def main():
import multiprocessing
# 创建队列
q = Manager().Queue()
# 创建进程池
# 默认情况, 进程池的个数为计算机CPU核数-1; Pool(3)
pool = Pool()
pool.apply_async(write, (q,))
pool.apply_async(read, (q,))
pool.close()
pool.join()
print("进程间通信结束!")
print("主进程的pid:%s, 父进程的pid为:%s" %(os.getpid(), os.getppid()))
if __name__ == "__main__":
main()