zoukankan      html  css  js  c++  java
  • python多进程和多线程

    多任务才有多进程和线程:

    线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。

    多进程和多线程的程序涉及到同步、数据共享的问题,编写起来更复杂。

    子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

    1.fock()只在linux/unix下可以使用 os.fork()

    2.multiprocessing:

    from multiprocessing import Process
    import os
    def run_proc(name):
    print('The child process No. is %s(%s)' % (name,os.getpid()))
    if __name__=='__main__':
    print('Parent process %s ' % os.getpid())
    p = Process(target=run_proc,args=('test',))
    p.start()
    p.join()
    print('END')

    3.Pool

    如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

    #Pool
    from multiprocessing import Pool
    import os,time,random
    def long_time_task(name):
    print('Task %d(%s) is running...' % (name,os.getpid()))
    start = time.time()
    time.sleep(random.random() * 3)
    stop = time.time()
    print('Task %d runs %.3f seconds!' % (name,(stop-start)) )

    if __name__ =='__main__':
    print('Parent process %s ' % os.getpid())
    pool = Pool(4)
    for i in range(8):
    pool.apply_async(long_time_task,args=(i,))

    print('Waiting all subprocesses done....')
    pool.close()
    pool.join()
    print('All subprocesses done.')

    4.子进程

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

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

    import subprocess
    print('$ nslookup www.baidu.com')
    o = subprocess.call(['nslookup','www.baidu.com'])
    print('exit code:',o)

    如果子进程还需要输入,则可以通过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('GBK'))
    print('Exit code:', p.returncode)

    5. 进程间通信

     from multiprocessing import Process,Queue
    import os,time,random

    # def write(q):
    # print('Process to Write:%d' % os.getpid())
    # for value in ['A','B','C']:
    # print('Put %s to queue...' % value)
    # q.put(value)
    # time.sleep(random.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:%d' % os.getpid())
    # while True:
    # value = q.get(True)
    # print('Get %s from queue!' %value)

    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__':
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))

    pw.start()
    # dddddddddddd
    pr.start()

    pw.join()

    pr.terminate()

    小结:

    1.linux和unix 可以使用fock()调用多进程

    2.多操作系统通用的,可以用multiprocessing模块中的Process(target =函数,args(name,)),Pool,subprocess

    3.进程间通信可以通过Queue、Pipes

    多线程:

    多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。

    lock = threading.Lock()

    t = threading.Thread(targat = func,args=(n,))

    Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。

  • 相关阅读:
    The difference of the line-height:2 and line-height:2em
    Damao眼中的新媒体
    Damao教你如何使用MacDown
    SF Pro 项目中的css hack
    刷新一次,图片更换一次
    Markdown 初体验
    docker 部署gitlab 构建CI/CD流水线
    c#面向对象问题 WPF简单数据驱动
    WebApi的创建和调试(简单步骤)
    C语言实现的贪吃蛇小游戏
  • 原文地址:https://www.cnblogs.com/wuchenggong/p/8824806.html
Copyright © 2011-2022 走看看