“忙等待”与“睡眠”的权衡是什么?
- 2024-11-14 08:30:00
- admin 原创
- 63
问题描述:
这是我上一个问题的延伸
unix/linux 套接字中的阻塞模式如何工作?
我现在从互联网上了解到,所有调用阻塞调用的进程都将处于休眠状态,直到调度程序找到解除阻塞的原因。原因可能多种多样,从缓冲区空到缓冲区满或任何其他情况。
但是,这能成为一种有效的实时方法吗,比如硬实时/稳实时应用程序?因为当解除阻塞条件成立时,进程不会被解除阻塞,而是当调度程序为进程分配 CPU 片,并且解除阻塞条件都成立时,进程才会被解除阻塞。
就好像你想要一个响应的解决方案,我不认为“自旋锁”或“忙等待”是正确的方法,CPU 切片被浪费,并且整个系统将变得无响应或可能响应不佳。
有人可以澄清这些矛盾的想法吗?
解决方案 1:
进入睡眠状态直到调度程序唤醒您是正常/首选的做法。
旋转(不睡觉的等待的另一种方式)不太常见,有以下效果:
保持 CPU 忙碌,并防止其他线程使用 CPU(直到/除非旋转线程完成其时间片并被抢占)
可以在您等待的事情发生的那一刻停止旋转(因为您正在不断检查该事件,并且您不需要花时间被唤醒,因为您已经醒了)
不调用进入睡眠状态和再次唤醒所需的 CPU 指令
如果延迟时间很短(例如,如果延迟的时间仅仅与执行 100 条 CPU 指令的时间一样长),那么旋转可能比进入睡眠状态更有效率(总 CPU 更少)。
解决方案 2:
自旋锁会烧毁 CPU 和轮询的资源路径,导致持续的资源浪费,而所需的事件却不会发生。
阻塞操作最重要的不同之处在于,它省去了 CPU 和相关资源路径,并wait
在预期发生事件的资源上安装某种形式。
在多任务或多线程/处理器环境中(长期以来的常见情况),当所需事件尚未到达时,可能还有其他操作,消耗 CPU 和资源访问路径会导致处理能力和时间的极大浪费。
当我们拥有超线程系统(我认为您在问题中提到了这一点)时,需要注意的是,CPU 线程的切片粒度非常高。我还要坚持观察,所有事件(您倾向于阻止的事件)都需要足够的时间才能发生,从而补偿它们在解除阻塞之前必须额外等待的短时间片。
我认为J-16
重点是休眠(阻塞)线程在阻塞状态下未使用其代码和数据空间的情况。这可能会导致系统放弃资源(如数据/代码缓存),然后在释放块时需要重新填充这些资源。因此,根据情况,阻塞可能会导致更多的资源浪费。
这也是一个有效的注意事项,应该在设计和实施中检查。
但是,在大多数情况下,阻塞通常比自旋锁更好。
解决方案 3:
如果在您的应用程序的用例中,上下文切换比消耗几个 CPU 周期更昂贵,因为您的条件必须保证在短时间内得到满足,那么忙等待可能对您有好处。
cond_wait()
否则,您可以通过睡眠或ing强制放弃 CPU 。
我能想到的强制上下文切换的另一种情况如下:
while(condition)
sleep(0);
解决方案 4:
首先你有一个误解:
阻塞调用不是“忙等待”或“自旋锁”。阻塞调用是可休眠的 - 这意味着 CPU 可以执行其他任务,不会浪费 CPU。
关于拦截来电的问题
阻塞调用更容易 —— 它们易于理解、易于开发、易于调试。
但是它们非常耗资源。如果你不使用线程,它会阻塞其他客户端;如果你使用线程,每个线程都会占用内存和其他系统资源。即使你有足够的内存,切换线程也会使缓存变冷并降低性能。
这是一种权衡——更快的开发和可维护性?或可扩展性。
解决方案 5:
我会尽量切中要点,因为其他答案已经提供了足够的解释,是的,通过从所有这些答案中学习,我认为应该有一个完整的画面。 ---
我认为权衡应在系统的响应性与吞吐量之间。
响应能力——可以从两个角度考虑
整体系统响应能力,以及
特定或每个进程的响应能力
我认为,为了提高系统的响应能力,阻塞调用是最好的方法。因为当阻塞调用处于阻塞状态时,它会将 CPU 交给就绪队列中的其他进程。
当然,对于特定的进程或每个进程的响应能力,我们应该考虑忙等待/自旋锁模型。
现在,为了提高整个系统的响应能力,我们不能减少调度程序的时间片(细粒度),因为这会在上下文切换中浪费太多的 CPU 资源。因此系统的吞吐量将大幅下降。当然,阻塞模型显然会增加系统的吞吐量,因为阻塞调用不会消耗 CPU 片并将其交给就绪队列中的另一个/下一个进程。
我认为最好的做法是——设计一个考虑每个进程响应能力的系统,不影响整体响应能力和吞吐量——通过实现基于优先级的调度程序,并考虑优先级反转问题,如果增加复杂性不会困扰你的话:)。
解决方案 6:
//改编自ASPI原版源代码...
DWORD startStopUnit (HANDLE handle, BOOL bLoEj, BOOL bStart)
{
DWORD dwStatus;
HANDLE heventSRB;
SRB_ExecSCSICmd s;
//here
heventSRB = CreateEvent (NULL, TRUE, FALSE, NULL);
memset (&s, 0, sizeof (s));
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
s.SRB_HaID = 0;
s.SRB_Target = 0;
s.SRB_Lun = 0;
s.SRB_Flags = SRB_EVENT_NOTIFY;
s.SRB_SenseLen = SENSE_LEN;
s.SRB_CDBLen = 6;
s.SRB_PostProc = (LPVOID) heventSRB;
s.CDBByte[0] = 0x1B;
s.CDBByte[4] |= bLoEj ? 0x02 : 0x00;
s.CDBByte[4] |= bStart ? 0x01 : 0x00;
ResetEvent (heventSRB);
dwStatus = SPTISendASPI32Command (handle,(LPSRB) & s);
if (dwStatus == SS_PENDING)
{
//and here, don´t know a better way to wait for something to finish without processor cicles
WaitForSingleObject (heventSRB, DEFWAITLEN);
}
CloseHandle (heventSRB);
if (s.SRB_Status != SS_COMP)
{
printf("Erro
");
return SS_ERR;
}
printf("nao Erro
");
return s.SRB_Status;
}
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件