msleep() 是否为其他线程提供循环

Does msleep() give cycles to other threads?

本文关键字:线程 循环 其他 是否 msleep      更新时间:2023-10-16

在多线程应用程序中,是

while (result->Status == Result::InProgress) Sleep(50);
//process results

while (result->Status == Result::InProgress);
//process results

?通过这一点,我问第一种方法在等待结果时是否会对其他线程有礼貌,而不是不断旋转?我正在等待的操作通常需要大约 1-2 秒,并且在不同的线程上。

我建议在这种情况下使用信号量而不是轮询。如果您更喜欢主动等待,睡眠比不断评估循环条件要好得多。

它更好,但不是很多。

只要result->Statusvolatile,编译器就可以减少

while(result->Status == Result::InProgress);

if(result->Status == Result::InProgress) for(;;) ;

因为条件在循环内没有改变。

调用外部(因此隐式volatile)函数Sleep更改此设置,因为这可能会修改result结构,除非编译器知道Sleep从不修改数据。因此,根据编译器的不同,第二个实现进入无限循环的可能性要小得多。

也不能保证对result->Status的访问是原子的。对于特定的内存布局和处理器体系结构,读取和写入此变量可能包含多个步骤,这意味着调度程序可能会决定在中间介入。

由于此时您正在通信的只是简单的是/否,并且接收线程也应该等待否定回复,因此最好的方法是使用操作系统提供的适当的线程同步原语来实现此效果。这样做的好处是,当条件发生变化时,您的线程会立即被唤醒,并且在此期间它不使用 CPU,因为操作系统知道您的线程正在等待什么。

在 Windows 上,使用

CreateEvent 和 co. 使用事件对象进行通信;在 Unix 上,使用 pthread_cond_t 对象。

是的,睡眠和变体放弃了处理器。其他线程可以接管。但是有更好的方法来等待其他线程。

不要使用空循环。

这也取决于您的操作系统调度策略。例如,Linux默认具有CFS调度,因此它将公平地将处理器分配给所有任务。但是,如果您使用FIFO策略将此线程设置为实时线程,则没有睡眠的代码将永远不会重新释放处理器,除非出现更高优先级的线程,否则在中断循环之前,将永远不会安排相同优先级或更低的优先级。如果您应用SCHED_RR则相同优先级和更高优先级的进程将被安排,但不会更低。