首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python多进程编程:突破GIL的限制

写代码越久,越发现Python的GIL像个套在脖子上的紧箍咒,特别是跑CPU密集型任务的时候。说实话,一开始我也被GIL坑惨了,代码放多核机器上跑,愣是只用一个核。后来发现用多进程能完美解决这个问题,干脆今天就来聊聊这个话题。

GIL是个啥

你就想啊,Python解释器本质上就是个大管家,要时刻盯着程序里的那些变量对象。为了防止多个线程同时修改一个对象,搞出个GIL(Global Interpreter Lock)。说白了就是个大锁,同一时间只让一个线程执行Python字节码。

import threading

import time

counter = 0

def increment():

global counter

for _ in range(1000000):

counter += 1

# 创建两个线程

t1 = threading.Thread(target=increment)

t2 = threading.Thread(target=increment)

start = time.perf_counter()

t1.start()

t2.start()

t1.join()

t2.join()

end = time.perf_counter()

print(f“最终结果: {counter}”) # 预期200万

print(f“耗时: {end - start:.2f}秒”)

小贴士:

GIL不是Python语言特性,是CPython解释器的实现细节

PyPy和Jython等其他Python实现就没这个限制

IO密集型任务用多线程就够了,GIL影响不大

多进程来救场

要绕过GIL,最简单的招就是用多进程。每个进程都有自己独立的Python解释器,互不干扰。multiprocessing这个库简直就是为这个场景量身定做的。

from multiprocessing import Process, Value

import time

def heavy_calculation(result):

temp = 0

for i in range(50000000):

temp += i

result.value = temp

if __name__ == '__main__':

# 创建共享内存值

result1 = Value('i', 0)

result2 = Value('i', 0)

# 启动两个进程

start = time.perf_counter()

p1 = Process(target=heavy_calculation, args=(result1,))

p2 = Process(target=heavy_calculation, args=(result2,))

p1.start()

p2.start()

p1.join()

p2.join()

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O_c8EpWpLhu5GyjxNx6pW5uQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券