Python 2.7 - Linux - 无限循环,将CPU放弃到其他线程/进程

时间:2016-02-03 09:22:39

标签: python linux multithreading sleep cpu-usage

有没有办法将其余的线程/进程分配时间放到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解决方案。

2 个答案:

答案 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%。