先看一个示例:
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()