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

    先看一个示例:

    import os
    
    # fork只能用于linux/unix中
    pid = os.fork()  # 给我们新建一个子进程
    print("贾维斯")
    if pid == 0:  # 实际上就是子进程
        print('子进程 {} ,父进程是: {}.'.format(os.getpid(), os.getppid()))
    else:
        print('我是父进程:{}.'.format(pid))

    运行如下:

    贾维斯
    我是父进程:24474
    贾维斯
    子进程24474,父进程是:24473

    首先贾维斯运行了两次

    为什么呢?

    虽然fork了子进程,但是主进程依然会继续执行,子进程会将主进程的所有数据全部拷贝到子进程中去,包括代码的运行。所以进程之间的数据是完全的隔离的

    import multiprocessing
    
    #多进程编程
    import time
    def get_html(n):
        time.sleep(n)
        print("sub_progress success")
        return n
    
    
    if __name__ == "__main__":
        progress = multiprocessing.Process(target=get_html, args=(2,))
        print(progress.pid)
        progress.start()
        print(progress.pid)
        progress.join()
        print("main progress end")

    一定要注意,在Windows下面一定需要在if __name__ == "__main__":下面不然会报错

    import multiprocessing
    
    #多进程编程
    import time
    def get_html(n):
        time.sleep(n)
        print("sub_progress success")
        return n
    
    
    if __name__ == "__main__":
        # progress = multiprocessing.Process(target=get_html, args=(2,))
        # print(progress.pid)
        # progress.start()
        # print(progress.pid)
        # progress.join()
        # print("main progress end")
    
        #使用线程池
        pool = multiprocessing.Pool(multiprocessing.cpu_count())
        # result = pool.apply_async(get_html, args=(3,))
        #
        # #等待所有任务完成
        # pool.close()
        # pool.join()
        #
        # print(result.get())
    
        #imap
        # for result in pool.imap(get_html, [1,5,3]):
        #     print("{} sleep success".format(result))
    
        for result in pool.imap_unordered(get_html, [1,5,3]):
            print("{} sleep success".format(result))

    需要注意的是pool.join()必须在pool.closed,就是不让pool不再接收新的任务

    join()是等待所有任务执行完成之后

    2,进程间的通信:

    共享全局变量不能适用于多进程编程,可以适用于多线程

    使用Pine

    #通过pipe实现进程间通信
    #pipe的性能高于queue
    
    # def producer(pipe):
    #     pipe.send("bobby")
    #
    # def consumer(pipe):
    #     print(pipe.recv())
    #
    # if __name__ == "__main__":
    #     recevie_pipe, send_pipe = Pipe()
    #     #pipe只能适用于两个进程
    #     my_producer= Process(target=producer, args=(send_pipe, ))
    #     my_consumer = Process(target=consumer, args=(recevie_pipe,))
    #
    #     my_producer.start()
    #     my_consumer.start()
    #     my_producer.join()
    #     my_consumer.join()
    
    # 这个是模仿线程共享变量通信使用Manager()方法 def add_data(p_dict, key, value): p_dict[key] = value if __name__ == "__main__": progress_dict = Manager().dict() from queue import PriorityQueue first_progress = Process(target=add_data, args=(progress_dict, "bobby1", 22)) second_progress = Process(target=add_data, args=(progress_dict, "bobby2", 23)) first_progress.start() second_progress.start() first_progress.join() second_progress.join() print(progress_dict)

    使用队列

    multiprocessing中的queue不能用于pool进程池
    pool中的进程间通信需要使用manager中的queue
    
    def producer(queue):
        queue.put("a")
        time.sleep(2)
    
    def consumer(queue):
        time.sleep(2)
        data = queue.get()
        print(data)
    
    if __name__ == "__main__":
        queue = Manager().Queue(10)
        pool = Pool(2)
    
        pool.apply_async(producer, args=(queue,))
        pool.apply_async(consumer, args=(queue,))
    
        pool.close()
        pool.join()
  • 相关阅读:
    【focus-lei 】微服务
    queryURLParams
    时间字符串的处理
    str.charAt()与str[]的区别
    数组去重函数封装
    数组去重的几种方法
    splice与slice区别
    变量与属性名的区别
    parseInt parseFloat Number三者转换的方式
    原生js实现选项卡样式切换的几种方式。
  • 原文地址:https://www.cnblogs.com/zhoulixiansen/p/10165621.html
Copyright © 2011-2022 走看看