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

posted @ 2022-11-13 20:20  钟鼎山林  阅读(40)  评论(0)    收藏  举报