多进程(multiprocessing)

import multiprocessing
import os, time


def info(title):
    print(title)
    # time.sleep(1)
    print("Module name:", __name__)
    print("Parent process id:", os.getppid())   #父进程id
    print("Current process id:", os.getpid())  #当前进程id
    print("\n\n")

# if __name__ == "__main__":     #启动一个子进程
#     info("Main process")
#     p = multiprocessing.Process(target=info, args=('Child process',))
#     p.start()

if __name__ == "__main__":     #启动多个子进程(查看结果)
    info("Main process")
    for i in range(10):
        p = multiprocessing.Process(target=info, args=('Child process %s' %i,))
        p.start()

注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

进程间通信

不同进程之间内存是不共享的,要想实现两个进程间的数据交换,有以下方法:

进程队列(Queue)

使用方法跟threading里的queue差不多(进程Queue使用pickle数据传递)

import multiprocessing, time

def put_func(qq):
    qq.put([12, None, "hello"])
    # time.sleep(2)
    # print("put:",qq.qsize())

def get_func(qq):
    print(qq.get())

if __name__ == "__main__":
    q = multiprocessing.Queue()         #创建一个进程Queue对象
    puter = multiprocessing.Process(target=put_func,args=(q,))    #将Queue对象传递到新创建的子进程中
    puter.start()

    geter = multiprocessing.Process(target=get_func, args=(q,))
    geter.start()
Pipe

pipe()返回一对连接对象,conn1, conn2代表了pipe的两端。每个对象都有send()和recv()方法。

from multiprocessing import Pipe,Process
import time

# a_conn, b_conn = Pipe()
# a_conn.send(['a', 'f', 'e'])
# print(b_conn.recv())

def f(conn):
    time.sleep(2)
    conn.send(['a', 'b', 'c'])

def ff(conn):
    print(conn.recv())

if __name__ == "__main__":
    conn1, conn2 = Pipe()
    p1 = Process(target=f, args=(conn2,))
    p2 = Process(target=ff ,args=(conn1,))
    # p1.daemon = True    # 加上daemon属性
    # p2.daemon = True
    p1.start()
    p2.start()
Manager

Python实现多进程间通信的方式有很多种,例如队列,管道等。但是这些方式只适用于多个进程都是源于同一个父进程的情况。如果多个进程不是源于同一个父进程,只能用共享内存,信号量等方式,但是这些方式对于复杂的数据结构,例如Queue,dict,list等,使用起来比较麻烦,不够灵活。
Manager是一种较为高级的多进程通信方式,它能支持Python支持的的任何数据结构。
它的原理是:先启动一个ManagerServer进程,这个进程是阻塞的,它监听一个socket,然后其他进程(ManagerClient)通过socket来连接到ManagerServer,实现通信。

from multiprocessing import Process, Manager
import os

def f(d, l):
    d[os.getpid()] = os.getpid()
    d[1] = '1'
    l.append(os.getpid())
    print(l)

if __name__ == "__main__":
    with Manager() as manager:    #manager = multiprocessing.Manager()
        d = manager.dict()          ## 生成一个可在多个进程间共享和传递的字典
        l = manager.list(range(5))  ##生成一个可在多个进程间共享和传递的列表

        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()

        print(d)
        print(l)

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。进程池设置最好等于CPU核心数量

进程池中有两个方法:
• apply 串行
• apply_async

from multiprocessing import Process, Pool
import time, os

def Foo(i):
    time.sleep(2)
    return  i+100

def Bar(arg):
    print(os.getpid())    #使用的主进程做的回调(os.getpid()值是一样的)
    print(arg)


if __name__ == '__main__':
    pool = Pool(3)       #进程池同时可放3个进程
    for i in range(10):
        # pool.apply(func=Foo, args=(i,))
        pool.apply_async(func=Foo, args=(i,), callback=Bar)  #callback回调,func执行完毕后执行回调函数,注意:使用的主进程做的回调

    print('end')
    pool.close()   # 一定要先关闭进程池再join
    pool.join()  #进程池中的进程执行完毕后再关闭,如果注释,程序就直接关闭了
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • @(python)[笔记] 目录 一、什么是进程 1.1 进程的概念 进程的概念起源于操作系统,是操作系统最核心的...
    CaiGuangyin阅读 1,244评论 0 9
  • Python 多进程 multiprocessing.Pool类详解 multiprocessing模块 mult...
    很少更新了阅读 9,665评论 2 14
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,107评论 29 470
  • 本文是我在学习 Python 多进程过程中的一些总结,主要介绍多进程的实现方式以及进程间的通信,大体有如下这么几点...
    柏丘君阅读 583评论 0 0
  • multiprocessing是一个使用类似于线程模块的API来支持产卵过程的软件包。 多处理包提供本地和远程并发...
    xin激流勇进阅读 576评论 0 0