多进程

windows和unix/linux系统的区别:

unix/linux系统提供了一个fork()系统调用,普通函数调用一次返回一次,而fork()调用一次返回两次。
而windows系统上没有fork()调用


第一种方法创建子进程:linux/unix独有
    linux/unix系统使用fork()函数创建子进程,模式如下:
    #!/usr/bin/env python
    import os
    print "process %s start....." % (os.getpid())

    pid=os.fork()                        pid有两种值,一种是0(代表子进程),另外一种是子进程ID(代表父进程)
    if pid == 0:                        当pid=0的时候,os.getpid()得到子进程,os.getppid()得到父进程
        print "child process %s and parent process %s" % (os.getpid(),os.getppid())
    else:                                否则pid等于子进程ID,os.getpid()得到父进程    
        print "I am parent %s create %s " % (os.getpid(),pid)


第二种方法:通过一个multiprocess模块中的类Process来创建子进程。通用linux,windows ,unix

    from multiprocessing import Process
    import os

    def run_proc(name):
        print "run child process %s %s...." % (name,os.getpid())

    if __name__ == "__main__":
        print "parent process %s..." % (os.getpid())
        p=Process(target=run_proc,args=("test",))           创建一个Process类的实例,并且传入一个函数和参数
        print "child process will start"
        p.start()                                    通过start来启动
        p.join()                                    join方法可以等待子进程结束后再往下继续执行    ,用于进程间同步
        print "child process end"
    

第三中方法:用进程池批量创建子进程

   方法一:我们通过Pool类创建出25各进程,然后再创建100各任务,然后每个进程执行4个任务,并把执行后的结果放在一个列表中,最后我们通过.get遍历这个列表把结果取出来
   
    #!/usr/bin/env python
    import multiprocessing
    import sys,os,time

    print "Parent process:%s" % (os.getpid())
    result=[]
    def run(h):
        print "threading test:",h,os.getpid()            
        time.sleep(2)                                        
    p=multiprocessing.Pool(processes=25)                一次创建25各进程。
                                                                                            
    for i in range(100):                                
        result.append(p.apply_async(run,('%s'%i,)))        执行run函数100次,并把执行的结果放在一个列表中,相当于每个进行执行函数4次

    p.close()                                                                    
    p.join()

    for res in  result:
        res.get(timeout=5)                                通过.get获取列表中的元素
        
    
    方法二:不需要通过列表,也可得出执行后的结果
    
    #!/usr/bin/env python
    #! -*- encoding:utf-8 -*-
    from multiprocessing import Pool
    import os,time,random

    def long_time_task(name):
        print "run tas %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(5)
        for i in xrange(5):
            p.apply_async(long_time_task,args=(i,))            
        print "waiting for all subprocess done "        
        p.close()                    join方法可以等待子进程结束后再往下继续执行,在join之前要先close,close之后不会添加新的process
        p.join()                            

    

    注意:如果我们有5各cpu,然后我们创建5个进程,执行5个任务的话,那么平均每个进程会占用一个cpu,并且执行一个任务,这时5各任务会同时执行,看不到等待效果。

    
    
    
------进程间的通信机制:通过Queue,Pipes来交换数据---------
'''

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","d"]:
        print "put %s to queue.." % value
        q.put(value)
        time.sleep(random.random())

def read(q):                                        #定义一个读函数
    print "process %s to read" % os.getpid()
    while True:
        value = q.get(True)
        print "get %s from queue" % value

if __name__ == "__main__":
    q=Queue()                                   #创建Queue对象
    pw=Process(target=write,args=(q,))          #创建一个写进程
    pr=Process(target=read,args=(q,))           #创建一个读进程

    pw.start()                          #开启读进程
    pr.start()                          #开启写进程

    pw.join()                       #等待写进程结束

    pr.terminate()                  #由于读进程用的是死循环,无法等待其结束,只有强制结束   

posted @ 2017-02-19 22:16  hehe88  阅读(129)  评论(0)    收藏  举报