os.getpid()是返回当前进程id,os.getppid()是返回父进程的id。

  • fork调用(unix/linux专用,不适用于windows)

参考:多进程-廖雪峰

import os

print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
  • multiprocessing(跨平台实现)

process方法是创立了子线程实例,用p.start()方法去启动,p.join()实现进程间的同步.

join()作用是让主线程等待子线程全部进行完了之后再进行。

缺陷是这样创建多个进程的话十分麻烦,那样的话就最好使用进程池(Pool)

import os
from multiprocessing import Process
# 子进程要执行的代码
def run_proc(name):
    print ('Child process %s (%s) Running...' % (name, os.getpid()))
if __name__ == '__main__':
    print ( 'Parent process %s.' % os.getpid())
    for i in range(5):
        p = Process(target=run_proc, args=(str(i),))
        print ( 'Process will start.')
        p.start()
    p.join()
    print ('Process end.')

  • Pool(快速创建多个进程)

.close()是关闭以后调用process的机会

join()作用是让主线程等待子线程全部进行完了之后再进行。

看下面的例子,看哪个waiting它是很难确定的,因为它也可能在我们一次运行的四个子进程前就运行了,外面的本身就属于父进程的范畴,要使最后一句all 最后一个执行有什么办法,就是前面加p.join()。(具体可以在linux上面测试)

processes=3为手动设置cpu核数,而且跟系统硬件支持的核心数关系也不大,可以设置大一点
from multiprocessing import Pool
import os, time, random

def long_time_task(name):
    print('Run task %s (%s)...' % (name, os.getpid()))
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
    print('Task %s runs %0.2f seconds.' % (name, (end - start)))

if __name__=='__main__':
    print('Parent process %s.' % os.getpid())
    p = Pool(processes=3)
    for i in range(4):
        p.apply_async(long_time_task, args=(i,))
    print('Waiting for all subprocesses done...')
    p.close()
    p.join()
    print('All subprocesses done.')

进程间通信

Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。

  • Queue(主要用于多个进程间通信)
from multiprocessing import Process, Queue
import os, time, random

# 写数据进程执行的代码:
def write(q):
    print('Process to write: %s' % os.getpid())
    for value in ['A', 'B', 'C']:
        print('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())

# 读数据进程执行的代码:
def read(q):
    print('Process to read: %s' % os.getpid())
    while True:
        value = q.get(True)
        print('Get %s from queue.' % value)

if __name__=='__main__':
    # 父进程创建Queue,并传给各个子进程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()
    # 启动子进程pr,读取:
    pr.start()
    # 等待pw结束:
    pw.join()
    # pr进程里是死循环,无法等待其结束,只能强行终止:
    pr.terminate()
  • Pipe(常用于两个进程间通信)
import multiprocessing
import random
import time,os
def proc_send(pipe,urls):
    for url in urls:
        print ("process(%s) send: %s" %(os.getpid(),url))
        pipe.send(url)
        time.sleep(random.random())
def proc_recv(pipe):
    while True:
        print ("Process(%s) rev:%s" %(os.getpid(),pipe.recv()))
        time.sleep(random.random())
if __name__== "__main__":
    pipe=multiprocessing.Pipe()
    p1=multiprocessing.Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10)]))
    p2=multiprocessing.Process(target=proc_recv,args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

results matching ""

    No results matching ""