绕过 GIL 的雷区:并发 Python 的冒险指南

  • python
  • 并发
  • GIL
  • 多线程
  • 多进程

了解 GIL 的局限性

GIL 是 Python 中的一个机制,它一次只允许一个线程执行字节码。这对于内存管理和线程安全至关重要,但它也限制了多线程程序的并行性。GIL 主要影响 CPU 密集型任务,因为它们无法并行执行。

绕过 GIL 的技巧

有几种方法可以绕过 GIL 的限制:

  • 使用多进程:进程是独立于 GIL 的,因此您可以使用多进程来执行 CPU 密集型任务。代码示例:
import multiprocessing

def task(n):
# 执行 CPU 密集型任务
return n * n

if __name__ == "__main__":
pool = multiprocessing.Pool(4)# 创建一个进程池
results = pool.map(task, range(10000))# 使用进程池执行任务
print(results)
  • 使用 GIL 友好的库:某些库(如 concurrent.futures 和 multiprocessing.dummy) 是 GIL 友好的,它们使用协程或多进程来绕过 GIL。代码示例:
import concurrent.futures

def task(n):
# 执行 CPU 密集型任务
return n * n

if __name__ == "__main__":
with concurrent.futures.ThreadPoolExecutor() as executor:
results = executor.map(task, range(10000))# 使用 GIL 友好的线程池执行任务
print(results)
  • 使用 C 扩展:GIL 仅适用于 Python 字节码,因此您可以使用 C 扩展来执行 CPU 密集型任务。不过,这需要更高级别的编程技巧。代码示例:
#include 

static PyObject* task(PyObject* self, PyObject* args) {
int n;
if (!PyArg_ParseTuple(args, "i", &n)) {
return NULL;
}
// 执行 CPU 密集型任务
int result = n * n;
return Py_BuildValue("i", result);
}

static PyMethodDef methods[] = {
{"task", task, METH_VARARGS, "Task function"},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"mymodule",
NULL,
-1,
methods
};

PyMODINIT_FUNC PyInit_mymodule(void) {
return PyModule_Create(&module);
}
  • 使用 asyncio:asyncio 是 Python 的异步 I/O 库,它使用协程来绕过 GIL。代码示例:
import asyncio

async def task(n):
# 执行 CPU 密集型任务
return n * n

async def main():
tasks = [task(i) for i in range(10000)]
results = await asyncio.gather(*tasks)# 并行执行任务
print(results)

if __name__ == "__main__":
asyncio.run(main())

注意事项

在绕过 GIL 时,需要注意以下几点:

  • 数据争用:绕过 GIL 可能导致数据争用,因此需要使用同步原语(如)来保护共享数据。
  • 调试困难:绕过 GIL 可能使调试变得困难,因为多个线程可能会同时执行。
  • 性能考虑:绕过 GIL 并不总是能提高性能,尤其是在 GIL 锁争用严重的情况下。

结论

绕过 GIL 是提高 Python 并发性的一种强大方法,但它也需要谨慎使用。通过使用多进程、GIL 友好的库、C 扩展或 asyncio,您可以绕过 GIL 的限制,同时避免潜在的陷阱。通过仔细考虑和适当的实现,您可以充分利用 Python 的并发功能,提高应用程序的性能和可扩展性。

以上就是绕过 GIL 的雷区:并发 Python 的冒险指南的详细内容,更多请关注昆居客【www.kunjuke.com】。

相关推荐:

研究员发现 ChatGPT 暗藏漏洞,可通过提示词注入绕过文件访问限制

7 月 6 日消息,安全人员 zer0dac 在 Medium 发文,披露了 ChatGPT 存在的一项安全漏洞。相应漏洞可允许黑客利用提示词注入(Prompt Injection)和路径遍历(Path Traversal)技术绕过部分文件访问限制,获取额外数据。目前该安全人员已将漏洞提报给 OpenAI,相应漏洞已于近期修复。根据 zer0dac 的说明,当用户向 ChatGPT 上传文件后,系...

Rufus 4.15 正式版发布:修复微软 Win11 安装绕过与静默安装问题,新增 RISC-V 64 UEFI 支持

感谢网友 吉茵珂絲 的线索投递! 7 月 1 日消息,继 Ventoy 针对新版 Secure Boot 进行适配后,Rufus 也在今天早些时候推出了 4.15 版本的最终正式版。作为微软官方媒体创建工具(MCT)的替代方案,Rufus 允许用户创建可启动 USB 安装介质,其优势在于能够绕过 Windows 11 的安装限制,甚至支持在完全不兼容的硬件上部署系统。此次更新的 4.15 正式版相...

Safari浏览器网页图片保存不了怎么办_Safari右键失效绕过与截图技巧

Safari网页图片无法保存时,iOS可用整页截图裁图、拷贝图像中转、关闭内容拦截器或切换桌面版网站;Mac端可查开发者工具资源、捕获全尺寸截图或用打印PDF提取。 你在Safari里看到一张想保存的网页图片,鼠标右键没反应、长按也没弹出“保存图像”选项,页面明明显示着图,却像被锁住一样无法下载——这不是你的操作问题,而是 Safari 对部分图片实施了交互屏蔽或资源加载拦截。 iOS设备:绕过右...

Trae的AI能帮忙做接口的并发压力测试脚本编写吗?

可采用四种方法生成压力测试脚本:一、Python+Locust编写可调试脚本;二、JMeter+CSV生成jmx参数化脚本;三、k6生成ES6轻量脚本用于CI/CD;四、curl+parallel命令行快速验证接口吞吐。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 如果您希望使用Trae的AI辅助生成接口并发压力测试脚本,但发现其未直接输...
· AI · 90685

夸克网盘限速怎么绕过实现高速下载_夸克云盘资源传输性能优化方案

夸克网盘限速可通过五种方案突破:一、启用快传实现局域网直连下载达3~5MB/s;二、油猴脚本提取直链配合多线程下载器;三、利用发送记录页“下载到本地”调用内生加速通道;四、开通超级会员获取专属带宽队列,千兆宽带下可达90MB/s以上;五、修改客户端网络配置提升吞吐效率。 如果您在使用夸克网盘下载文件时发现速度被强制限制在数百KB/s,通常是因为平台对非会员用户启用了默认带宽配额策略,或未激活高速传...

通义万象API并发调用限制是多少?高并发场景下的解决方案

通义万象API出现429错误时,应先确认模型并发阈值(如wanx-v1为10 QPS、wan2.6-t2v为5 QPS),再通过切换低敏感模型、降低输出分辨率、禁用高级特性、客户端信号量限流及动态错峰调度等五类方法协同应对。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 如果您调用通义万象API时遇到“429 Too Many Reques...

谷歌浏览器怎么配置下载任务的并发连接数_谷歌浏览器自带下载器极限提速

Chrome下载速度未达带宽上限主因是默认单连接策略,可通过启用并行下载、禁用QUIC、优化DNS、外接Aria2及关闭后台干扰五步优化。 如果您在使用谷歌浏览器下载文件时发现速度未达网络带宽上限,很可能是其默认下载器采用单连接或低并发策略所致。Chrome 自带下载器的并发行为受实验性标志、协议栈配置及系统级资源调度共同影响。以下是可直接生效的多种配置路径: 一、启用并行下载功能(官方内置多线程...

千问API的并发限制是多少?高并发调用的限流策略与解决方案

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 如果您调用通义千问API时遭遇请求被拒绝、返回“RateLimitExceeded”错误或响应头中包含Retry-After字段,则极有可能已触及当前账号或模型的并发调用限制。以下是应对该问题的多种可行方案: 一、确认当前所用模型及对应并发配额标准 通义千问的并发限制以每分钟调用次数(QPM)和...