python多进程

      程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
      在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。

有了进程为什么还要线程?
      进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:

进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

      线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务


一、多进程的创建方法
多进程和多线程的使用方法基本一样,只是导入的模块不同,方法是一样的

import threading                           #线程的模块
threading.Thread(target=,args=())          #执行线程采用的方法

import multiprocessing                     #进程的模块
multiprocessing.Process(target=,args=())   #执行进程采用的方法

二、进程之间数据共享
进程之间数据共享用multiprocessing的Manager方法

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from multiprocessing import Process, Manager
def MemoryManger(dic, lis):
    dic['aaa'] = 'xyz'
    dic[1] = 111111
    dic['2'] = 222222
    dic[0.25] = None
    lis.append('xyz')
    #print(lis)
if __name__ == '__main__':
    with Manager() as manager:
        m_dict = manager.dict()                #生成一个字典
        m_list = manager.list(range(5))        #生成一个列表
        res_list = []
        for i in range(10):
            p = Process(target=MemoryManger, args=(m_dict, m_list))
            res_list.append(p)
        for res in res_list:
            res.start()
            res.join()

        print(m_dict)
        print(m_list)

三、进程池(同一时间有多少个进程在CPU上运行)
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

from multiprocessing import Pool
import time,os
def Foo(num):
    time.sleep(1)
    print('this process pid is %s' % os.getpid())
    return num + 100

def Bar(arg):
    '''
    这个是一个回调函数,主进程回调的
    :param arg:
    :return:
    '''
    print('--> exec done',arg,os.getpid())

if __name__ == '__main__':
    pool = Pool(5)
    print('main process pid is %s' % os.getpid())    #主进程的pid
    for i in range(10):
        pool.apply_async(func=Foo,args=(i,),callback=Bar)  #回调函数是由主进程调用的
    print('end'.center(20,'='))
    pool.close()  #进程池中进程执行完后再关闭
    pool.join()

备注:
1、进程是有两个方法,apply(串行方式),apply_async(并行方式)
2、在关闭的时候,必须是先close,再join。这个顺序不能颠倒

四、进程之间相互通信
不同进程间内存是不共享的,要想实现两个进程间的数据交换,需要一个中间件(队列或者管道)
1、队列

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from multiprocessing import Process, Queue
def f(q):
    q.put(['id','name','age'])


if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())   #从队列里面取值
    p.join()

备注:
在生成进程的时候,先把 q 传进去,但实际上是克隆了一份(在 f 函数里面),在传进去的时候,即生成进程的时候,pickle序列化了一下,当线程访问的时候,又pickle反序列化。

2、管道

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from multiprocessing import Process, Pipe
def f(conn):
    conn.send(['id','name','age'])
    conn.close()
if __name__ == '__main__':
    parent_con, child_con = Pipe()
    p = Process(target=f, args=(child_con,))
    p.start()
    print(parent_con.recv())  # prints "[42, None, 'hello']"
    p.join()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值