python 学习总结2 多进程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 学习总结2 多进程相关的知识,希望对你有一定的参考价值。

多进程:

我们什么时候需要多进程呢?我们知道python的多线程,实际不是真实的多线程,它同一时间在一个cpu执行一个任务,它通过上下文的切换来让我看起来是多并发的,

那么如果我们想要真正实现多个任务在多个cpu上同时执行,我们就需要多进程的性质来帮忙了(python的多线程不适合cpu密集型的任务,适合io密集型的任务)。

import multiprocessing
import threading

def thread_run():
    print(threading.get_ident())
def run():
    print("ok")
    t=threading.Thread(target=thread_run(),)
    t.start()
if __name__=="__main__":
    for i in range(10):
        p=multiprocessing.Process(target=run,)
        p.start()

上端代码体现了多进程用法其实就是在形式上与多线程是大同小异的!

通过学习多线程我们知道所有的线程都是有一个父线程

from multiprocessing import Process
import os


def info(title):
    print(title)
    #os.getppid 显示父线程的id
    print(parent process:, os.getppid())
    #os.getid显示子线程的id
    print(process id:, os.getpid())
    print("\n\n")


def f(name):
    info(\033[31;1mcalled from child process function f\033[0m)
    print(hello, name)

if __name__ == __main__:
    info(\033[32;1mmain process line\033[0m)
    p = Process(target=f, args=(bob,))
    p.start()

通过上面的代码,我们在主线程调用info显示了 主线程相对的 父线程,与子线程,而且我们发现父线程就是pycharm本身,其子线程作为相对于这段代码子线程的主线程,通过这段代码我们了解了Python的主线程与子线程之间的关系

多进程Queue:

那么我们如何实现主线程与子线程公用一块数据呢,也就是我们怎么才能实现两个进程之间的交互呢?看下文

多进程的Queue与线程中的队列是不同的,注意不能在多进程中调用线程的Queue因为每个线程都有各自占用一块内存,多线程是共享一块内存的,本质上是不同的

import multiprocessing
def f(qq):
    print("in child:",qq.qsize())
    qq.put([42, None, hello])
if __name__ == __main__:
    q = multiprocessing.Queue()
    q.put("test123")
    p = multiprocessing.Process(target=f, args=(q,))
    p.start()
    p.join()

多进程的pipes与manager:

我们的管道实际上就像socket 一样 ,其实就是相互收发的过程

from multiprocessing import Process, Pipe


def f(conn):
    #在子线程发送信息
    conn.send([42, None, hello from child])
    conn.send([42, None, hello from child3])
    print("",conn.recv())
    conn.close()


if __name__ == __main__:
  #注意建立的顺序,有两个其实顺序无所谓,注意后面的接受顺序就好
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print("parent",parent_conn.recv())  # prints "[42, None, ‘hello‘]"
    print("parent",parent_conn.recv())  # prints "[42, None, ‘hello‘]"
    parent_conn.send(" from hshs")  # prints "[42, None, ‘hello‘]"
    p.join()
下面是manager的用法 ,实际上都类似,体现了两个进程分享一些
from multiprocessing import Process, Manager
import os

def f(d, l):
    d[1] = 1
    d[2] = 2
    d["pid%s" %os.getpid()] = os.getpid()
    l.append(1)
    print(l,d)


if __name__ == __main__:
    with Manager() as 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()
        l.append("from parent")
        print(d)
        print(l)

 

数据进行修改

 

以上是关于python 学习总结2 多进程的主要内容,如果未能解决你的问题,请参考以下文章

学习java第19天个人总结

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

多进程学习总结

4月27日 python学习总结 GIL进程池线程池同步异步阻塞非阻塞

基于Windows平台的Python多线程及多进程学习小结

[Python3] 043 多线程 简介