python多线程多进程线程池_[Python 多线程] multiprocessing、多进程、工作进程池 (十四)...

由于Python的GIL限制,多线程未必是CPU密集型程序的好的选择。

多进程可以完全独立的进程环境中运行程序,可以充分地利用多处理器。

但是进程本身的隔离性带来的数据不共享也是一个问题。而且线程比进程轻量级。

multiprocessing

Process类

Process类遵循了Thread类的API,减少了学习难度。(几乎和Thread类使用方法一模一样)

上一篇文章里最后使用了多线程来解决CPU密集型的例子,但发现多线程和多线程最终执行效率几乎相同,多线程并没有想象中的优势。

上一篇中多线程的例子:

#模拟CPU密集型 多线程

import threading,logging,time,random,datetime

DATEFMT="%H:%M:%S"

FORMAT = "[%(asctime)s]\t [%(threadName)s,%(thread)d] %(message)s"

logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt=DATEFMT)

def calc():

sum = 0

for _ in range(100000000):

sum += 1

start =datetime.datetime.now()

t1 = threading.Thread(target=calc)

t2 = threading.Thread(target=calc)

t3 = threading.Thread(target=calc)

t4 = threading.Thread(target=calc)

t5 = threading.Thread(target=calc)

t1.start()

t2.start()

t3.start()

t4.start()

t5.start()

t1.join()

t2.join()

t3.join()

t4.join()

t5.join()

print('aaa')

delta = (datetime.datetime.now() -start).total_seconds()

print(delta)

#运行结果:

aaa

53.135543

此例子是单线程情况下执行耗时58秒左右。

再使用多进程的例子来看一下是否可以有所不同:

#=========多进程、真正的并行、适用于CPU计算密集型===============

import multiprocessing

import datetime

def calc(i):

sum = 0

for _ in range(100000000):

sum += 1

# print(i,sum)

if __name__ == "__main__":

start = datetime.datetime.now()

lst = []

for i in range(5):

p = multiprocessing.Process(target=calc,args=(i,),name='p-{}'.format(i))

p.start()

lst.append(p)

for p in lst:

p.join()

delta = (datetime.datetime.now() - start).total_seconds()

print(delta)

运行结果:

24.767709

从耗时结果可以看出多线程的执行效率明显得要比多线程(其实就是单线程)高得多。

进程间同步:

进程间同步提供了和线程同步一样的类,使用方法一样,使用的效果也类似。

不过,进程间代价要高于线程,而且底层😡实现是不同的,只不过Python屏蔽了这些,让用户简单使用。

multiprocessing还提供共享内存、服务器进程来共享数据,还提供了Queue队列、Pipe管道用于进程间通信。

通信方式不同:

多线程就是启动多个解释器进程,进程间通信必须序列化、反序列化

数据的线程安全性问题

由于每个进程中没有实现多线程,GIL可以说没什么用了。

进程池举例:

进程池只能由创建它的进程使用

# 进程池

import multiprocessing

import datetime

def calc(i):

sum = 0

for _ in range(100000000):

sum += 1

if __name__ == "__main__":

start = datetime.datetime.now()

pool = multiprocessing.Pool(5) #定义同时至多起几个线程

for i in range(5):

pool.apply_async(calc,args=(i,))

pool.close()

pool.join()

#多线程

# lst = []

# for i in range(5):

# p = multiprocessing.Process(target=calc,args=(i,),name='p-{}'.format(i))

# p.start()

# lst.append(p)

#

# for p in lst:

# p.join()

delta = (datetime.datetime.now() - start).total_seconds()

print(delta)

运行结果:

24.944169

多进程、多线程的选择

1、CPU密集型

CPython中使用到了GIL,多线程的时候锁相互竞争,且多核优势不能发挥,Python多进程效率更高。

2、IO密集型

适合是用多线程,减少IO序列化开销。且在IO等待的时候,切换到其它线程继续执行,效率不错。

应用:

请求/应答模型:WEB应用中常见的处理模型

master启动多个worker工作进程,一般和CPU数目相同。

worker工作进程中启动多线程,提高并发处理能力。worker处理用户的请求,往往需要等待数据。

这就是nginx工作模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值