python 多进程

2018-12-09  本文已影响0人  y_7539

多任务编程

进程

什么是进程

1.程序就是没有执行的二进制代码

2.进程就是运行的程序

进程调度

时间片轮转:

cpu不会闲置,会将要运行的程序轮换执行(例如要运行qq和微信,可能会将qq先运行0.1秒,然后再将微信执行0.2秒,运行多少时间是随机的)

并发:交替运行

并行:同一时间点一起运行

fork创建进程

import os
#返回进程的pid
pid = os.fork()
if pid == 0:
    print("我是子进程")
else:
    print("我是主进程")

实例

import os
import time
def sing():
    for i in range(5):
        print("唱歌")
def dance():
    for i in range(5):
        print("跳舞")
#开始时间
start = time.time()
#创建多进程
pid = os.fork()
if pid == 0:
    sing()
else:
    dance()
print(time.time() - start) 
1.父程序和子程序运行顺序是随机的
2.fork得到的结果是0,那么这个程序就是子程序。如果不是0,那么这个进程就是父进程,并且这个结果就是其子进程的pid
3.os.getpid() 得到当前进程的id
4.os.getppid()  得到当前进程父进程的id

修改全局变量

import os

num = 0
#创建进程
pid = os.fork()
if pid == 0:
    num += 1
    print(num)
else:
    num += 1
    print(num)
总结:子进程在创建的时候会复制父进程的内存到自己的内存中

多次fork

import os

#创建进程
pid = os.fork()
if pid == 0:
    #子进程打印1
    print(1)
else:
    #父进程打印2
    print(2)
#两个进程再生成进程
pid = os.fork()
#父进程新生成的子进程和子进程生成的进程打印3
if pid == 0:
    print(3)
#父进程打印4, 子进程打印4
else:
    print(4)

总共会打印6次
注意:fork实现的多进程只能运用在linux系统

Process实现多进程

#导包
import os
import time
from multiprocessing import Process
#定义两个方法
def sing():
    print("sing里面的:{}".format(os.getpid()))
    for i in range(5):
        print("唱歌")
        time.sleep(1)
def dance():
    print("dance里面的:{}".format(os.getpid()))
    for i in range(5):
        print("跳舞")
        time.sleep(1)
#定义多进程方法
def process():
    #创建进程
    ps = Process(target=sing)
    #启动进程
    ps.start()
    #创建进程,执行某个方法
    pd = Process(target=dance)
    pd.start()
    print("process里面的:{}".format(os.getpid()))
#Windows下,多进程必须放在这个方法下才能运行
if __name__ == "__main__":
    process()

进程对象.join()方法   等待当前进程执行完毕再往下执行
#Process参数

#windows 实现多进程
import os
import time
from multiprocessing import Process

def sing(x):
    for i in range(x):
        print("唱歌")
        time.sleep(1)
def dance(x, name):
    for i in range(x):
        print(f"{name}跳舞")
        time.sleep(1)

def process():
    start = time.time()
    ps = Process(target=sing, args=(5,))   
    ps.start()
    pd = Process(target=dance, args=(10,), kwargs={"name": "ddd"})
    pd.start()
    #等待子进程执行完毕,再执行
    ps.join()
    pd.join()
    print(time.time() - start)

if __name__ == "__main__":
    process()

Process类继承

代码

#导入进程类
from multiprocessing import Process
#继承类
class ProcessClass(Process):
    #初始化
    def __init__(self, name):
        super(ProcessClass, self).__init__()
        self.name = name
    #run 方法必须写,调用start就是调用这个方法
    def run(self):
        print(self.name + "ok")


if __name__ == '__main__':
    p = ProcessClass("python")
    p.start()

进程池

解决每一个任务创建一个进程占用内存空间大的问题

import os
import time
from multiprocessing import Pool


# 打印方法
def work(msg):
    print(f"{os.getpid()},{msg}")
    time.sleep(1)


# 创建3个进程池
pool = Pool(3)

for i in range(8):
    # 多进程异步调用打印方法
    pool.apply_async(work, (i,))

# 关闭进程池
pool.close()
# 等待进程执行完毕
pool.join()

进程间的通信

队列

import os
import time
from multiprocessing import Queue, Process


# 定义一个写函数,往队列里写

def write(q):
    for i in ["吕布", "貂蝉", "小乔", "周瑜"]:
        q.put(i)
        print(f"{os.getpid()}在写{i}")
        time.sleep(1)


# 定义一个读方法,从队列里读取
def read(q):
    while True:
        if not q.empty():
            print(f"{os.getpid()}在读{q.get()}")
            time.sleep(1)
        else:
            break


if __name__ == '__main__':
    # 定义一个队列,不传参数,有多少塞多少
    q = Queue()
    # 创建子进程,把队列作为参数传入目标函数中
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动进程
    pw.start()
    # pw写入完毕再执行读
    pw.join()
    pr.start()
    pr.join()

其他

孤儿进程:父进程先于子进程执行完毕
僵尸进程:子进程执行完后,父进程还在沉睡,没有去回收子进程的内存空间
    执行top可以查看进程  zombie代表僵尸进程的数量
    找出僵尸进程 后面带<defunct>的就是僵尸    ps -ef | grep "def"
    如何结束僵尸进程:结束其父进程    kill -9 僵尸进程的ppid
守护进程:父进程先于子进程执行完毕,子进程会被1号进程接管,就会变成守护进程
上一篇 下一篇

猜你喜欢

热点阅读