C 语言插件可以默认摆脱 Python 的 GIL 约束吗?为什么测试结果不是如此?
資深大佬 : black11black 3
如题,最近用 cyhton 写了个加速插件,给 python 中的某个模块加速了两百倍左右,效果十分满意。
于是又给算法复杂度加了十倍,这次 c 也顶不住了,单个函数调用时间一分钟左右。
于是想到了多线程,因为 python 进入 3.6 时代后异步逐渐完善,日常里使用 python 多线程的地方主要还是在 IO,通过异步 IO 复用解决得很开心,所以很久没有用过多线程模块了。
按照我记忆中的只是,python 的 GIL 机制是,如果你调用 C 插件的话是会默认释放 GIL 锁的,也就是说应该是原生使用多线程,并且在每个线程中调用 c 插件的话,它应该是可以利用多核心的,于是写了个简单小测试,但是结果不太对。我最终的结果还是顺序执行的时间,并没有利用多核心加速,是哪里做错了吗,还是我记错了,带佬来说一下。
简单 demo 代码如下:
# timer.py import zhishu import time from threading import Thread thread_list = [Thread(target = zhishu , args = (150000 , )) for _ in range(8)] st_time = time.time() for _ in thread_list: _.start() for _ in thread_list: _.join() print(time.time() - st_time)
这个简单 demo 创建了 8 个线程,每个线程调用一个名叫 zhishu 的由 cython 编写的函数,这个函数的作用是计算 n 以内质数数量,我本机上单次调用大概需要 2s,我有 8 颗核心,理论上我期望他在 2s 内完成全部计算,但是最终得到的结果却是 16s
cython 代码: 一个简单的质数计算器
# zhishu.pyx import cython def zhishu(n): cdef cython.int count = 0 cdef cython.int i , j , nn nn = <cython.int> n for i in range(2 , n): for j in range(2 , i): if (i%j == 0): break else: count += 1 return count
感谢!
大佬有話說 (5)