Loading

python中的进程

进程:顾名思义,运行中的程序

一、创建进程的方式:(2种)

两种方式都是利用multiprocessing模块导入Process类来实现具体方法看代码

第一种:

from multiprocessing import Process
import time


# 创建的子程序代码
def task(name):
    print('%s is running' % name)
    time.sleep(2)
    print('%s is over' % name)

# 注意,在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍
# 一定要写在if __name__ == '__main__':代码块里面
# 强调:函数名一旦加括号,执行优先级最高,立刻执行
# 主程序
if __name__ == '__main__':
    p1 = Process(target=task, args=('egon', ))
    p1.start()    # 告诉操作系统创建一个进程
    print('主程序打印打印')

第二种:

from multiprocessing import Process
import time

class MyProcess(Process):

    def __init__(self, name):
        super().__init__()
        self.name = name

    # 必须写run方法
    def run(self):
        print('%s is running' % self.name)
        time.sleep(1)
        print('%s is end' % self.name)

if __name__ == '__main__':
    obj = MyProcess('egon')
    obj.start()
    print('主程序')

两种方法其实过程大致相同,实现方式略微有点差别

结果都是:

主进程正在运行
egon is running!
egon is end!

子进程对象.start()方法:向操作系统发出请求:说我要创建个子进程了,快帮我搞一个。

此时start处的代码相当于异步继续向下执行,执行速度肯定会快于操作系统收到请求然后选择性的创建子进程,所以主程序执行完了,子进程的代码才开始执行。

要想让子进程先执行,然后执行下面的主程序的话,可以在子进程下面来个.join(),意思是你子进程先走,我等你搞定了我再进行接下来的主进程代码!

from multiprocessing import Process
import time

def task(name):
    print('%s is running!' % name)
    time.sleep(2)
    print('%s is end!' %name)

if __name__ == '__main__':
    p = Process(target=task, args=('egon', ))
    p.start()
    p.join()
    print('主进程继续运行')

# 结果
egon is running!
egon is end!
主进程正在运行

一次性创建多个子程序:

from multiprocessing import Process
import time

def task(name):
    print('%s正在运行。。。。。' %name)
    time.sleep(2)
    print('%s运行结束。。。。。' %name)


if __name__ == '__main__':
    p_list = []
    for i in range(1,4):
        p = Process(target=task, args=('进程[%s]' % i, ))
        p.start()
        p_list.append(p)
    for n in p_list:
        n.join()
    print('主进程继续进行!')

 二、进程之间的数据是互相隔离的,无法共享

 # 记住 进程与进程之间数据是隔离的!!!
from multiprocessing import Process


x = 100

def task():
    global x
    x = 1


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()
    print('',x)

三、进程之间的数据通信:

进程之间无法交互数据,因为进程与进程之间是相互隔离的,如果要实现数据的通信,可以间接的通过一些方法去实现:比如队列

队列相当于给进程间创造了一个公共管道,数据的通信通过这个管道进行。

from multiprocessing import Process,JoinableQueue
import time
import random

def producer(name, food, q):
    for i in range(1,5):
        data = '%s<%s>' % (food, i)
        time.sleep(random.randint(1, 2))
        q.put(data)
        print('[%s]造好了[%s]' % (name, data))

def consumer(name, q):
    while True:
        data = q.get()
        time.sleep(random.randint(1, 2))
        # if data is None: break
        print('[%s]吃了%s' % (name, data))
        q.task_done()

if __name__ == '__main__':
    q = JoinableQueue()
    p1 = Process(target=producer, args=('大佬', '酸奶', q))
    p2 = Process(target=producer, args=('DSB', '香蕉', q))
    c2 = Process(target=consumer, args=('SSSS', q))
    c1 = Process(target=consumer, args=('BBBB', q))
    p1.start()
    p2.start()
# 将c1、c2设置为守护进程,当主进程结束,守护进程会跟着结束 c1.daemon
= True c2.daemon = True c1.start() c2.start() p1.join() p2.join() q.join() print('主程序-到此一游')

四、生产者消费者模型

这个模型实际上就是队列的应用,主要用于进程间的数据交互。一个产生数据一个拿产生的数据,实现过程就是队列。

from multiprocessing import Process,JoinableQueue
import time
import random


def producer(name, food, q):
    for i in range(1, 5):
        data = '%s%s' % (food, i)
        time.sleep(random.randint(1, 2))
        print('%s已经做好了%s' % (name, data))
        q.put(data)


def consumer(name, q):
    while True:
        data = q.get()
        time.sleep(random.randint(1, 2))
        print('%s 消灭了一个%s' % (name, data))
        q.task_done()    # 每次取完数据之后,都会告诉队列一声:我这次取完了


if __name__ == '__main__':
    q = JoinableQueue()    # 生成一个队列对象
    p1 = Process(target=producer, args=('小明', '包子', q))
    p2 = Process(target=producer, args=('小黄', '馒头', q))
    c1 = Process(target=consumer, args=('根根', q))
    c2 = Process(target=consumer, args=('矮矮', q))
    p1.start()
    p2.start()
    c1.daemon = True    # 守护进程,达到主进程结束,这个子进程也会一起结束
    c2.daemon = True    # 守护进程,达到主进程结束,这个子进程也会一起结束
    c1.start()
    c2.start()
    p1.join()     # 生产者完成所有生成之后才能进行下一步
    p2.join()
    q.join()    # 等待队列中的数据全部取出,才能往下走
    print('')

 

posted @ 2019-05-06 19:57  MrSu  阅读(442)  评论(0编辑  收藏  举报