【问题标题】:Does sleep() system call have any drawbacks?sleep() 系统调用有什么缺点吗?
【发布时间】:2019-11-09 06:28:33
【问题描述】:

所以我的目标是执行由线程处理的一段代码(假设线程 1 使用 POSIX 线程),同时取消执行它各自任务的不同线程(线程 2)。线程 1 在发生特定事件时启动(基于时间的事件 - 在我的情况下为 60 秒)。

为此,我使用了sleep() 函数。但是我的导师告诉我,在多线程程序中使用 sleep 是一种不好的做法。我无法理解他的推理。所以我决定逃到这里。

如果我的问题看起来太模糊,提及sleep() 的任何缺点将不胜感激。

【问题讨论】:

  • 好的设计是使用定时器并等待它们的结果。Sleep 基本上会做同样的事情,但看起来不太好。 ;-) 好的,真正的原因是当您等待计时器时,您也可以在 sleep 仅休眠时等待其他事情。
  • 我喜欢这个问题,但如果它是在softwareengineering.stackexchange.com 而不是 SO,我会更喜欢它。我不知道如何要求版主将它移到那里。我可以投票将其移至其他五个 stackexchange 站点中的任何一个,但软件工程不是选择之一。 :-(
  • 对不起,我是这个平台的新用户,下次会更周到。 :-)

标签: c thread-safety pthreads sleep


【解决方案1】:

有一些同步原语允许一个线程等待另一个线程(例如互斥锁、信号量、条件变量)。 sleep() 也会让你的线程等待,但是你要么睡一个不必要的长时间(如果另一个线程需要更长的时间,这可能还不够),或者你必须检查另一个线程是否已经完成(你无论如何都需要保护原子变量或互斥锁)。

因此,对于线程同步,sleep 是不够的,而且会使一切变得复杂(+ 减慢速度)。

【讨论】:

  • 对于上述问题的性质不清楚,我深表歉意。所以这两个线程共享的唯一共享资源是队列。因此,数据在队列中累积 60 秒。线程 2 应该每秒将数据排入队列(在无限循环中),而线程 2 等待 60 秒并将该时间范围内累积的所有数据出列。我使用了起始指针和结束指针(入队和出队操作)来确保任一线程不会相互干扰。所以我觉得不需要互斥锁。如果我错了,请纠正我,顺便感谢您的输入
  • 如果没有互斥体,编译器会看到线程 1 永远不会写入结束指针,并且可能会基于该假设进行优化,因此您需要一个互斥体。此外,线程 2 可能会被中断,因此不会在 60 秒内完成。
  • 谢谢,我想我对这个问题有了更好的理解。
【解决方案2】:

我的导师告诉我,在多线程程序中使用睡眠是一种不好的做法。

我会反对那种笼统的说法。

使用sleep() 作为在特定时间发生某事的方法的替代方法是 将任务提交给计时器。如果您有一个线程除了sleep() 之外什么都不做,直到某个时间然后 让一些事情发生,然后你可以使用计时器。而且,如果线程 有一个循环使事情定期发生,那么您可以使用 recurring 计时器事件,或者,重新提交自身的计时器事件。

如果你有多个线程,每个线程的存在只是让某件事发生在 某个时间,然后您可以通过使用 而是计时器对象。如果你的程序有 GUI,那么你就是 可能使用已经有一个可以使用的计时器的 GUI 框架, 所以即使有一个“计时”线程也可能会浪费资源。

但是,当您谈论线程时,您谈论的是您的架构 程序,当你在谈论sleep()时,你在谈论一个低级 实施细节。我会自动怀疑任何编程的硬性规则, 结合了来自如此广泛不同设计层次的想法。

如果我有一个充分的理由让我的程序中存在一个线程*,那么我会毫不犹豫地 编写创建它的代码,如果我有一个 充分的理由 将我的一个线程发送到sleep(),** 那么我会毫不犹豫地写下那个电话。


* 一个线程存在的一个很好的理由是管理一些有状态的“进程” 独立于程序内部发生的其他“过程”进行。

** 线程休眠的一个很好的理由是,如果有某种原因导致 在线程管理的复杂“进程”的两个步骤之间需要暂停。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    • 2011-02-28
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多