zoukankan      html  css  js  c++  java
  • x多进程

    #!/usr/bin/env python3

    # -*- coding: utf-8 -*-

    '''

    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',))

        print('Child process will start.')

        p.start()

        p.join()

        print('Child process end')

    '''

    #执行结果如下

    '''

    Parent process 4152.

    Child process will start.

    Run child process test(10456)...

    Child process end

    '''

    #创建子进程时,只需要传入一个执行函数和函数的参数,创建一个process实例,用start()方法启动,这样创建进程比fork()还要简单。

    #join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

    '''

    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(4)

        for i in range(5):

            p.apply_async(long_time_task,args=(i,))

        print('Wainting for all subprocesses done...')

        p.close()

        p.join()

        print('All subprocesses done...')

    '''

    #执行结果如下

    '''

    Parent process 9508 .

    Wainting for all subprocesses done...

    Run task 0(5084)...

    Run task 1(8540)...

    Run task 2(6500)...

    Run task 3(4756)...

    Task 1 runs 0.78 seconds.

    Run task 4(8540)...

    Task 4 runs 0.93 seconds.

    Task 0 runs 1.92 seconds.

    Task 3 runs 2.49 seconds.

    Task 2 runs 2.75 seconds.

    All subprocesses done...

    '''  

    #对POOL对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。

    #请注意输出的结果,task 0,1,2,3是立刻执行的,而task 4要等待前面某个task完成后才执行,这是因为POOL的默认大小在此电脑上是4,因此,最多同时

    #执行4个进程。这是Pool有意设计的限制,并不是操作系统的限制。如果改成:p=Pool(5),就可以同时跑5个进程。

    #由于POOL的默认大小是CPU的核数,如果你不幸拥有8核CPU,你要提交至少9个子进程才能看到上面的等待效果。

    #子进程

    #很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。

    #subprocess 模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。

    #下面演示如何在Python代码中运行命令nslookup www.python.org ,这和命令直接运行的效果是一样的:

    '''

    import subprocess

    print('$nslookup www.python.org')

    r=subprocess.call(['nslookup','www.python.org'])

    print('Exit code:',r)

    '''

    #执行结果如下:

    '''

    $nslookup www.python.org

    服务器:  dc.gticom.cn

    Address:  172.18.5.251

    非权威应答:

    名称:    python.map.fastly.net

    Addresses:  2a04:4e42:11::223

              151.101.72.223

    Aliases:  www.python.org

    Exit code: 0

    '''

    #如果子进程还需要输入,则可以通过communicate()方法输入:

    '''

    import subprocess

    print('$ nslookup')

    p= subprocess.Popen(['nslookup'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    output,err = p.communicate(b'set q=mx python.org exit ')

    print(output.decode('utf-8'))

    print('Exit code:',p.returncode)

    '''

    #上面的代码相当于在命令行执行命令nslookup,然后手动输入:

    '''

    set q=mx 

    python.org

    exit

    '''

    #上述代码未运行出来,暂不理会

    #进程间通信

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

    #以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:

    #队列是线程间最常用的交换数据的形式。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) # 调用对象的put()方法在队尾插入一个项目。

            time.sleep(random.random()) # time.sleep(n) 推迟调用线程的运行,表示将进程挂起 n 秒 。random.random 用于生成一个在区间[0,1)之间的随机浮点数。

    #读数据进程执行的代码:

    def read(q):

        print('Process to read:%s' % os.getpid())

        while True:

            value=q.get(True) # 调用队列对象的get()方法,从队头删除并返回一个项目。

            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()   #join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

        #pr 进程里是死循环,无法等待其结束,只能强行终止:

        pr.terminate()

    #Process ,创建进程的类:Process([group[,target[,name[,args[,kwargs]]]]]),target表示调用对象(一般为函数名),

    #args表示调用对象的位置参数(一般为函数的入参)元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。

    #输出结果如下:

    '''

    Process to write:7952

    Put A to queue...

    Process to read:13656

    Get A from queue.

    Put B to queue...

    Get B from queue.

    Put C to queue...

    Get C from queue.

    '''

    # 在Unix/Linux下,multiprocessing模块封装了fork()调用,使我们不需要关注fork()的细节。由于Windows没有fork调用,因此,multiprocessing需要‘模拟’出

    #fork的效果,父进程所有Python对象都必须通过pickle序列化再传到子进程去,所以,如果multiprocessing在Windows下调用失败了,要先考虑是不是pickle失败了。

    #在Unix/Linux下,可以使用fork()调用实现多进程。

    #要实现跨平台的多进程,可以使用multiprocessing模块

    #进程间通信是通过Queue、Pipes等实现的。

  • 相关阅读:
    Java基础——clone()方法浅析
    Unity shader error: “Too many texture interpolators would be used for ForwardBase pass”
    ar 解压一个.a文件报错: xxx.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
    How to set up "lldb_codesign" certificate!
    Unity-iPhone has Conflicting Provisioning Settings
    ETC1/DXT1 compressed textures are not supported when publishing to iPhone
    Xcode 提交APP时遇到 “has one iOS Distribution certificate but its private key is not installed”
    XCode iOS之应用程序标题本地化
    苹果电脑(Mac mini或Macbook或iMac)恢复出厂设置
    Unity 4.7 导出工程在XCode10.1上编译报错
  • 原文地址:https://www.cnblogs.com/Ting-light/p/9547347.html
Copyright © 2011-2022 走看看