Python中的进程池及进程池锁:multiprocessing.Pool及multiprocessing.Manager().Lock()

一、.同步与异步,指结果的返回方式:
同步,是所有的操作都做完,才返回结果。
异步,不用等所有操作都做完,即时返回结果。

二、.多进程与多线程的区别:

1、多线程可以共享全局变量,多进程不能。

2、多线程中,所有子线程的进程号相同;多进程中,不同的子进程进程号不同。

3、线程共享内存空间;进程的内存是独立的。

4、同一个进程的线程之间可以直接交流;两个进程想通信,必须通过一个中间代理来实现。

5、创建新线程很简单;创建新进程需要对其父进程进行一次克隆。

6、一个线程可以控制和操作同一进程里的其他线程;但是进程只能操作子进程。

7、两者最大的不同在于:在多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响;而多线程中,所有变量都由所有线程共享。

三、多线程的优势
进程只有一个,所以分配的CPU资源是一定的,多线程只不过是轮流抢占CPU而已,并不会真正提高处理速度。这意味着,多线程的作用主要在于提高了并发数
Python多线程相当于单核多线程,多线程有两个好处:CPU并行,IO并行,单核多线程相当于自断一臂。所以,在Python中,可以使用多线程,但不要指望能有效利用多核。如果一定要通过多线程利用多核,那只能通过C扩展来实现,不过这样就失去了Python简单易用的特点。不过,也不用过于担心,Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

四、进程池的概念:
定义一个池子,在里面放上固定数量的进程,有需求来了,就拿一个池中的进程来处理任务
等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待任务
如果有很多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行。
也就是说,进池中进程的数量是固定的,那么同一时间最多有固定数量的进程在运行
这样不会增加操作系统的调度难度,还节省了开关进程的时间,也一定程度上能够实现并发效果。
代码:

import time
import multiprocessing


class PrintNumber():

    def __init__(self, multi_num):
        self.multi_num = multi_num

    def run_task(self):
        sum_num = 1
        for i in range(5):
            sum_num = i
            time.sleep(1)
            print("multi_num = {}, output = {}".format(self.multi_num, sum_num))
        return self.multi_num,"ok"

def myCallBack(arg):
    print(arg)

if __name__ == "__main__":
    #numprocess 要创建的进程数,如果省略,将默认使用cpu_count()的值
    #initializer每个工作进程启动时要执行的可调用对象,默认为None
    #initargs传给initializer的参数组

    process_pool = multiprocessing.Pool()
    for i in range(3):
        a=1
        test = PrintNumber(i)
        process_pool.apply_async(test.run_task, args=(),callback=myCallBack)
    # close是不允许再向进程池中添加任务
    # 必须close+join,否则主进程跑完了,子进程还没完,就会报错
    process_pool.close()
    process_pool.join()
    print("thread join success!")

输出:

multi_num = 0, output = 0
multi_num = 1, output = 0
multi_num = 2, output = 0
multi_num = 0, output = 1
multi_num = 2, output = 1
multi_num = 1, output = 1
multi_num = 0, output = 2
multi_num = 2, output = 2
multi_num = 1, output = 2
multi_num = 0, output = 3
multi_num = 2, output = 3multi_num = 1, output = 3
multi_num = 0, output = 4
(0, 'ok')
multi_num = 1, output = 4
multi_num = 2, output = 4
(2, 'ok')
(1, 'ok')
thread join success!

进程池加锁:

import time
import multiprocessing


def get():
    for i in range(3):
        time.sleep(1)
        print(i)


def task(lock):
    lock.acquire()   #获取锁
    get()
    lock.release()   #释放锁


def myCallBack(arg):
    print(arg)

if __name__ == "__main__":
    #numprocess 要创建的进程数,如果省略,将默认使用cpu_count()的值
    #initializer每个工作进程启动时要执行的可调用对象,默认为None
    #initargs传给initializer的参数组
    #进程池的锁需要使用Manager().Lock()
    lock=multiprocessing.Manager().Lock()
    process_pool = multiprocessing.Pool()
    for i in range(3):
        process_pool.apply_async(task, args=(lock,))
    # close是不允许再向进程池中添加任务
    # 必须close+join,否则主进程跑完了,子进程还没完,就会报错
    process_pool.close()
    process_pool.join()

    print("thread join success!")

输出:

0
1
2
0
1
2
0
1
2
thread join success!
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Pythonmultiprocessing.Pool模块和multiprocessing.dummy.Pool模块都是用于创建进程池和线程池的工具。 进程池(multiprocessing.Pool)是一组维护在进程的工作者,它们可以并行地执行任务。该模块是基于multiprocessing模块实现的,它通过创建多个进程来并行执行任务。 下面是一个创建进程池的示例: ``` python import multiprocessing def worker(process_num): print("Process %d is working" % process_num) if __name__ == '__main__': pool = multiprocessing.Pool(processes=4) for i in range(5): pool.apply_async(worker, args=(i,)) pool.close() pool.join() ``` 上面的示例,我们创建了一个包含4个进程进程池,并向进程提交了5个任务,每个任务调用worker函数并传递一个进程编号作为参数。我们使用apply_async方法向进程提交任务,并使用close和join方法管理进程池。 线程池(multiprocessing.dummy.Pool)是一组维护在线程的工作者,它们可以并行地执行任务。该模块是基于threading模块实现的,它通过创建多个线程来并行执行任务。 下面是一个创建线程池的示例: ``` python from multiprocessing.dummy import Pool import time def worker(thread_num): print("Thread %d is working" % thread_num) time.sleep(1) if __name__ == '__main__': pool = Pool(4) for i in range(5): pool.apply_async(worker, args=(i,)) pool.close() pool.join() ``` 上面的示例,我们创建了一个包含4个线程的线程池,并向线程池提交了5个任务,每个任务调用worker函数并传递一个线程编号作为参数。我们使用apply_async方法向线程池提交任务,并使用close和join方法管理线程池。 需要注意的是,线程池和进程池的用法基本相同,但是由于线程在Python不能真正地并行执行,因此线程池的性能可能比进程池差。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颢师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值