有没有办法将其余的线程/进程分配时间放到Python 2.7中的其他线程/进程?
请不要推荐同步,互斥,信号量等。我要求在Windows或Linux上存在可用于访问内核函数的代码的标准机制。
让我举几个简短的C代码示例:
int i = 0
while (true) {
i++;
// this will work on windows:
sleep(0);
// and this will work on Linux
sched_yield();
}
当您编译并启动上面的代码时,如果您查看CPU使用情况,它将为0%,因为{i ++,如果为true / jump}消耗CPU分配给线程的时间的一小部分。其余的CPU时间代表其他线程/进程放弃。
相反,当你这样做时:
i = 0
while 1:
i = i + 1
time.sleep(0.001)
在Python中,CPU使用率很大程度上取决于传递给time.sleep函数的时间。通过的时间越少意味着CPU使用率越高。这对我来说绝对是不可接受的,并且在那里时间高于0.1。
请确保Linux上的python time.sleep(0)与Windows上的本机函数sleep(0)的工作方式不同。此外,请注意我没有在Windows上尝试使用Python,因为我正在寻找Linux解决方案。
答案 0 :(得分:1)
sched_yield()
的循环仍在使用一定的CPU时间(接近 0%,但不完全是0%)。该数量可能小于等效的Python解决方案,因为Python中的函数调用具有更多的开销。尽管如此,你的C解决方案还是非常完美。
如果在循环中递增一个整数,情况会变得更糟:在Python中,这是一个缓慢的操作,需要创建一个新对象。此外,C int
将溢出,Python int
将根据需要分配更多内存。
当你想要一个空闲的线程时,你通常会这样写:
while True:
time.sleep(100000) # 100000 or another very large number
这样,你减少了每秒函数调用的次数,实际上使函数调用所需的时间可以忽略不计。
答案 1 :(得分:0)
对我来说,C示例也使用100%的一个处理器。只是这些100%中的大部分都显示为系统调用中使用的时间。我推测sched_yield()
。这是我用过的完整的C程序:
#include <sched.h>
int main(int argc, char const *argv[])
{
int i = 0;
while (1) {
i++;
sched_yield();
}
return 0;
}
通过标准库中的ctypes
模块使用Python中的C函数可以看到类似的效果。主要区别在于过程与系统时间之间的比率。在Python中,还有很多工作涉及递增一个整数,它可以超出CPU寄存器的位数,并通过动态类型语言中的代理对象调用C函数。这是代码:
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import ctypes
LIBC = ctypes.CDLL('libc.so.6')
shed_yield = LIBC.sched_yield
def main():
i = 0
while True:
i += 1
shed_yield()
if __name__ == '__main__':
main()
在我试过的(相当慢的)系统上,系统调用大约占处理器负载的50%。