Python中进程

1、概述

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
多进程模式是实现多任务模式的一种,同时还有多线程、协程!

参考:百度百科—进程

2、进程创建

from multiprocessing import Process
from time import sleep
import os

m = 1  #通过m可以看出进程是独立的资源分配单位

def task1(s,name):
    global m
    while True:
        sleep(s)
        m += 1
        print('这是任务1....',os.getpid(),'------------',os.getppid(),name,'m:',m)
def task2(s,name):
    global m
    while True:
        sleep(s)
        m += 1
        print('这是任务2....',os.getpid(),'------------',os.getppid(),name,'m:',m)

number = 1
if __name__ == '__main__':
    #子进程
    #创建进程p1
    p1 = Process(target=task1,name = '任务1',args = (1,'aa'))
    #启动p1进程
    p1.start()
    print(p1.name)
    #创建p2进程
    p2 = Process(target=task2,name = '任务2',args =(2,'bb'))
    #启动p2进程
    p2.start()
    print(p2.name)
    while True:
        number += 1
        sleep(0.2)
        if number == 100:
            p1.terminate()  #终止进程
            p2.terminate()
            break
        else:
            print('---------------->number:',number)

总结:

from multiprocessing import Process
process = Process(target = 函数,name = 进程的名字,args = (给函数传递参数))

process 对象

对象调用方法:
process.start()  启动进程并执行任务
process.run()  只是执行了任务但是没有启动进程

terminate()  终止

注: 进程创建在不同类型os系统上创建方法不一样,上述进程是在windows10系统上创建的,以下编写代码也是在windows10系统上跑的。可以参考:Python语言,Linux下进程的创建,Windows下进程的创建

3、自定义进程

from multiprocessing import Process

class MyProcess(Process):
    def __init__(self,name):
        super(MyProcess,self).__init__()
        self.name = name
    # 重写run方法
    def run(self):
        n = 1
        while True:
            print('进程名字:'+self.name)
            print('-------->自定义进程,n:{}'.format(n,self.name))
            n += 1

if __name__ == '__main__':
    p1 = MyProcess('小明')
    p1.start()
    p2 = MyProcess('小红')

4、进程池

  1. 概念: 当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果是上百甚至上千目标,手动的去创建进程工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时。如果池还没有满,那么就会创建一个新的进程用来执行该请求,但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行。

  2. 非阻塞式进程池: 全部添加到就绪队列中,立刻返回,并没有等待其他的进程完毕,但回调函数是等待任务完成之后才调用。

    from multiprocessing import Pool
    import time
    from random import random
    import os
    #非阻塞式进程
    
    def task(task_name):
        print('开始做任务啦!',task_name)
        start = time.time()
        time.sleep(random() * 2)
        end = time.time()
        print('完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid()))
        return '完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid())
    
    container = []
    def callback_func(n):
        container.append(n)
        print(n)
    
    if __name__ == '__main__':
        pool = Pool(5) #跟主进程生命期一样
        tasks = ['听音乐','吃饭','洗衣服','打游戏','散步','看孩子','做饭']
        for task1 in tasks:
            pool.apply_async(task,args=(task1,),callback=callback_func) #非阻塞式,把所有队列加到就绪列表中
        pool.close() #添加任务结束
        pool.join() # 就是一堵墙,所有任务都结束后,就撤掉
    
        for i in container:
            print(i)
        print('over!!!!')
        
    
  3. 阻塞式进程池: 添加一个执行一个任务,如果一个任务不结束另一个任务就进不来。

    from multiprocessing import Pool
    import time
    from random import random
    import os
    
    def task(task_name):
        print('开始做任务啦!',task_name)
        start = time.time()
        time.sleep(random() * 2)
        end = time.time()
        print('完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid()))
        # return '完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid())
    
    # container = []
    # def callback_func(n):
    #     container.append(n)
    
    if __name__ == '__main__':
        pool = Pool(5) #跟主进程生命期一样,所以为了防止主进程提前结束,才调用了pool.join
        tasks = ['听音乐','吃饭','洗衣服','打游戏','散步','看孩子','做饭']
        for task1 in tasks:
            pool.apply(task,args=(task1,)) #阻塞式
        pool.close() #添加任务结束
        pool.join() # 就是一堵墙,所有任务都结束后,就撤掉
    
        # for i in container:
        #     print(i)
        print('over!!!!')
        
    
  4. 总结

    pool = Pool(max) 创建进程池对象,max表示进程池中的进程数量
    pool.apply() 阻塞的
    pool.apply_async  非阻塞的
    
    pool.close() 关闭池子
    pool.join() 主进程让步
    

5、队列

from multiprocessing import Queue
from multiprocessing import Process
from time import sleep
q = Queue(5)

q.put('A')
q.put('B')
q.put('C')
q.put('D')
q.put('E')
if not q.full():
    q.put('F',timeout=3)  #队列满了,这里阻塞了。
else :
    print('队列已满!')


#获取队列的值
for i in range(5):
    print(q.get(timeout=2))

6、进程间通信

def dowmload(q):
    images = ['girl.jpg','boy.jpg','man.jpg']
    for image in images:
        print('正在下载:',image)
        sleep(0.5)
        q.put(image)

def getfile(q):
    while True:
        try:
            file = q.get()
            print('{}正在上传,保存成功!'.format(file))
        except:
            print('全部保存完毕')
            break

if __name__ == '__main__':
    Q = Queue(5)
    p1 = Process(target=dowmload,args=(Q,))
    p2 = Process(target=getfile,args=(Q,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()
发布了84 篇原创文章 · 获赞 36 · 访问量 4538

猜你喜欢

转载自blog.csdn.net/qq_41475583/article/details/105003943