python -多进程
进程的概念
进程:通俗理解一个运行的程序或者软件,进程是操作系统资源分配的基本单位。
现实生活中的公司可以理解成是一个进程,公司提供办公资源(电脑、办公桌椅等),真正干活的是员工,员工可以理解成线程。
注意:一个程序至少有一个进程,一个进程至少有一个线程,多进程可以完成多任务.
1.2 进程的状态
工作中,任务数往往大于cpu的核数,即一定有一些任务正在执行,而另外一些任务在等待cpu进行执行,因此导致了有了不同的状态

- 就绪态:运行的条件都已经慢去,正在等在cpu执行
- 执行态:cpu正在执行其功能
- 等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态
小结
一个进程默认有一个线程,进程里面可以创建线程,线程是依附在进程里面的,没有进程就没有线程
import time
from concurrent.futures import ThreadPoolExecutor,as_completed
from concurrent.futures import ProcessPoolExecutor
# 多进程编程
# 耗cpu的操作 ,用多进程编程,
# 对于io操作来说 ,使用多线程编程,
# 进程切换代价要高于线程
# 斐波那契数
def fib(n):
if n <=2:
return 1
return fib(n-1)+fib(n-2)
# 对于io操作来说 多线程优于多进程
def random_sleep(n):
time.sleep(n)
return n
if __name__ == '__main__':
#多线程完成
# with ThreadPoolExecutor(3) as executor:
# all_task = [executor.submit(fib,(num)) for num in range(25,40)]
# start_time = time.time()
# for future in as_completed(all_task):
# data = future.result()
# print("exe result:{}".format(data))
# print('耗时:{}'.format(time.time()-start_time))
# 改为多进程,在window下 使用ProcessPoolExecutor() 要在main下
# with ProcessPoolExecutor(3) as executor:
# all_task = [executor.submit(fib,(num)) for num in range(25,35)]
# start_time = time.time()
# for future in as_completed(all_task):
# data = future.result()
# print("exe result:{}".format(data))
# print('耗时:{}'.format(time.time()-start_time))
# --------------io测试 # 对于耗cpu的操作 ,多进程优于多线程
#多线程完成
# with ThreadPoolExecutor(3) as executor:
# all_task = [executor.submit(random_sleep,(num)) for num in [2]*30]
# start_time = time.time()
# for future in as_completed(all_task):
# data = future.result()
# print("exe result:{}".format(data))
# print('耗时:{}'.format(time.time()-start_time))
# 多进程
with ProcessPoolExecutor(3) as executor:
all_task = [executor.submit(random_sleep,(num)) for num in [2]*30]
start_time = time.time()
for future in as_completed(all_task):
data = future.result()
print("exe result:{}".format(data))
print('耗时:{}'.format(time.time()-start_time))
multiprocessing 多进程
import time
from concurrent.futures import ProcessPoolExecutor
import multiprocessing
# 多进程编程
def get_html(n):
time.sleep(n)
print("sub_progress success")
return n
# 也可以类的形式
class MyProgress(multiprocessing.Process):
def run(self) -> None:
if __name__ == '__main__':
progress = multiprocessing.Process(target=get_html,args=(2,))
progress.start()
print(progress.pid) # 进程号
progress.join()
print("main progress end")
Process创建的实例对象的常用方法:
start():启动子进程实例(创建子进程)
join([timeout]):是否等待子进程执行结束,或等待多少秒
terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
pid:当前进程的pid(进程号)
进程池Pool
import time
# 多进程编程
from concurrent.futures import ProcessPoolExecutor
import multiprocessing
def get_html(n):
time.sleep(n)
print("sub_progress success")
return n
# 也可以类的形式
class MyProgress(multiprocessing.Process):
def run(self):
pass
if __name__ == '__main__':
# 使用进程池,指定进程数量 布置的默认cpu个数
pool = multiprocessing.Pool(multiprocessing.cpu_count())
# result=pool.apply_async(get_html,args=(3,)) # 添加一个任务
#
# pool.close() #关闭进程池
# pool.join() # 等待任务完成,在等待时 一定要先执行close 不在添加新任务
# print(result.get()) # 获取返回值
# imap ,和线程map差不多,返回的结果顺序和添加一致
# for result in pool.imap(get_html,[1,5,3]):
# print("{} sleep success".format(result))
# imap_unordered ,谁先完成返回谁
for result in pool.imap_unordered(get_html,[1,5,3]):
print("{} sleep success".format(result))
进程间通信
multiprocessing中的 queue
import time
from multiprocessing import Process,Queue,Manager,Pool
# 注意:进程间通信 不能在使用如下这个 Queue
# from queue import Queue
def producer(queue):
queue.put('a')
time.sleep(2)
def consumer(queue):
time.sleep(2)
data = queue.get()
print(data)
# 共享全局变量通信 不能适用于多进程编程,可以适用于多线程
# multiprocessing 中的queue 不能用于pool进程池
if __name__ == '__main__':
queue = Queue(10)
my_producer = Process(target=producer,args=(queue,))
my_consumer = Process(target=consumer,args=(queue,))
my_producer.start()
my_consumer.start()
my_producer.join()
my_consumer.join()
Manager对象的queue
import time
from multiprocessing import Process,Queue,Manager,Pool
# 注意:进程间通信 不能在使用如下这个 Queue
# from queue import Queue
def producer(queue):
queue.put('a')
time.sleep(2)
def consumer(queue):
time.sleep(2)
data = queue.get()
print(data)
# 共享全局变量通信 不能适用于多进程编程,可以适用于多线程
# multiprocessing 中的queue 不能用于pool进程池
# pool中的进程间通信需要使用manager 中的queue
if __name__ == '__main__':
queue = Manager().Queue()
pool = Pool()
pool.apply_async(producer,args=(queue,))
pool.apply_async(consumer,args=(queue,))
pool.close()
pool.join()
Pipe 通信
import time
from multiprocessing import Process,Queue,Manager,Pool,Pipe
# 注意:进程间通信 不能在使用如下这个 Queue
# from queue import Queue
def producer(pipe):
pipe.send('a')
time.sleep(2)
def consumer(pipe):
time.sleep(2)
data = pipe.recv()
print(data)
# 通过pipe 管道实现进程间通信 简化版的queue
# pipe 只能适用于两个进程间通信
# pipe 的性能高于queue
if __name__ == '__main__':
# 会实列化出来两个对象 一个接受 一个添加
recevie_pipe,send_pipe = Pipe()
pool = Pool()
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()
内容共享数据变量
import time
from multiprocessing import Process,Queue,Manager,Pool,Pipe
# 内存共享 Manager 里面数据类型
def add_data(p_dict,key,value):
p_dict[key] = value
if __name__ == '__main__':
progress_dict = Manager().dict()
first_progress = Process(target=add_data,args=(progress_dict,'number1',25))
second_progress = Process(target=add_data,args=(progress_dict,'number2',30))
first_progress.start()
second_progress.start()
first_progress.join()
second_progress.join()
print(progress_dict)
借鉴链接:https://juejin.cn/post/6970520987011907615
浙公网安备 33010602011771号