当前位置: 首页 > 面试题库 >

Linux下Python的time.sleep(0)的行为-是否引起上下文切换?

西门淮晨
2023-03-14
问题内容

这种模式经常出现,但我找不到直接的答案。

一个非关键,不友好的程序可能会

while(True):
    # do some work

使用其他技术和平台,如果要允许该程序热运行(尽可能多地使用CPU周期),但要有礼貌-允许其他正在热运行的程序有效地降低我的速度,您经常会这样写道:

while(True):
    #do some work
    time.sleep(0)

我已经读到了有关后一种方法是否可以在Linux机器上运行的python上实现我希望的信息的相互矛盾的信息。它会导致上下文切换,导致我上面提到的行为吗?

编辑:对于什么是有价值的,我们在Apple
OSX中尝试了一个小实验(没有方便的linux盒)。这个盒子有4个核心以及超线程,所以我们只用了一个就可以启动8个程序

while(True):
    i += 1

正如预期的那样,活动监视器将显示8个进程中的每个进程都消耗了95%以上的CPU(显然具有4个内核和超线程,您总共获得了800%)。然后,我们启动了第九个此类程序。现在所有这9个都在85%左右。现在杀死第九个人并启动一个程序

while(True):
    i += 1
    time.sleep(0)

我希望此过程将使用接近0%的资源,而其他8个将运行95%的资源。但是,所有九个国家的税率大约为85%。因此,在Apple
OSX上,sleep(0)似乎无效。


问题答案:

我从没考虑过,所以写了这个脚本

import time

while True:
    print "loop"
    time.sleep(0.5)

只是作为测试。通过运行此命令,strace -o isacontextswitch.strace -s512 python test.py可以在循环中获得以下输出:

write(1, "loop\n", 5)                   = 5
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
write(1, "loop\n", 5)                   = 5
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
write(1, "loop\n", 5)                   = 5
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
write(1, "loop\n", 5)                   = 5
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
write(1, "loop\n", 5)

select()是系统调用,所以是的,您是上下文切换(从技术上来说,切换到内核空间时实际上不需要上下文切换,但是如果您正在运行其他进程,那么您在这里的意思是除非您已经准备好数据以读取文件描述符,其他进程可以运行到那时)进入内核以执行此操作。有趣的是,延迟是在stdin上选择的。这使python可以根据需要中断诸如输入之类的事件的ctrl+c输入,而不必等待代码超时-
我认为这很简洁。

我应该注意,time.sleep(0)除了传入的时间参数为之外,其他情况均相同{0,0}。而且,自旋锁定对于非常短的延迟而言并不是真正理想的选择,multiprocessing并且threads具有等待事件对象的能力。

编辑 :所以我看了一下究竟是什么Linux。do_selectfs\select.c)中的实现进行此检查:

if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
    wait = NULL;
timed_out = 1;
}

if (end_time && !timed_out)
    slack = select_estimate_accuracy(end_time);

换句话说,如果提供了结束时间并且两个参数均为零(!0 =
1且在C中为true),则将等待时间设置为NULL,并且选择被视为超时。但是,这并不意味着函数会返回给您。它遍历您拥有并调用的所有文件描述符cond_resched,从而潜在地允许另一个进程运行。换句话说,发生的事情完全取决于调度程序。如果与其他进程相比,您的进程一直在浪费CPU时间,则很可能发生上下文切换。如果不是,您所处的任务(内核do_select函数)可能会一直执行到完成为止。

但是,我要重申的一点是,要更好地适应其他进程,最好的方法通常是使用自旋锁以外的其他机制。



 类似资料:
  • 本文向大家介绍什么是上下文切换?相关面试题,主要包含被问及什么是上下文切换?时的应答技巧和注意事项,需要的朋友参考一下 多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文

  • 多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时

  • 问题内容: 是否有关于Linux上同一进程的线程之间进行上下文切换的成本的任何良好的经验数据(主要是x86和x86_64)?我说的是一个线程在用户空间中执行的最后一条指令在自愿或非自愿进入睡眠之前执行的最后一个指令之间的周期数或纳秒数,同一进程的另一个线程在同一CPU /内核唤醒后执行的第一条指令之间的周期数或纳秒数。 我编写了一个快速测试程序,该程序在分配给同一cpu / core的2个线程中不

  • 问题内容: 我一直在想办法在python脚本中使用它,以使其在不同的间隔执行作业。伪代码如下所示: 总而言之,程序将hibernate直到需要执行下一个作业。它运行该作业,找到要运行的下一个作业,然后hibernate直到需要运行下一个作业(继续到无穷大)。我打算在Linux机器上运行它- 使用cron作业是可能的。有人对此有意见吗? 问题答案: 不,它不占用CPU。 该文件说: 暂停执行指定的秒

  • 同时,Puppy资源将更多地位于webMvc级别,并加载到DispatcherServlet的上下文中。 从我刚才读到的内容(现在我很有希望理解)来看,根上下文实际上是DispatcherServlet创建的上下文的‘父’上下文。这意味着根上下文中的bean实际上可以自动连接/注入到DispatcherServlet创建的上下文中的任何bean中。我只是了解了“嵌套”上下文的概念。这准确吗? 如果

  • 本文向大家介绍linux下上传下载文件夹的方法,包括了linux下上传下载文件夹的方法的使用技巧和注意事项,需要的朋友参考一下 Linux下目录复制:本机->远程服务器 test1为源目录,test2为目标目录,zhidao@192.168.0.1为远程服务器的用户名和ip地址。 Linux下目录复制:远程服务器->本机 zhidao@192.168.0.1为远程服务器的用户名和ip地址,test