如何在linux上实现线程安全计时器?

时间:2009-03-23 05:57:28

标签: linux thread-safety timer

正如我们所知,在信号处理程序中执行操作非常糟糕,因为它们在类似中断的上下文中运行。调用信号处理程序时,很可能会保存各种锁(包括malloc()堆锁!)。

所以我想在不使用信号机制的情况下实现线程安全计时器。

我该怎么办?

很抱歉,实际上,我不期待有关线程安全的答案,但是关于在Unix或Linux上实现线程安全的计时器的答案。

4 个答案:

答案 0 :(得分:4)

在你的帖子中使用usleep(3)或sleep(3)。这将阻止线程,直到超时到期。

如果您需要等待I / O并且在任何I / O就绪之前有一个计时器到期,请使用select(2),poll(2)或epoll(7)并超时。

如果您仍然需要使用信号处理程序,请使用pipe(2)创建管道,在线程的读取端执行阻塞读取,或使用select / poll / epoll等待它准备就绪,并且用write(2)在信号处理程序中写一个字节到管道的写端。你写入管道的内容并不重要 - 想法是让你的线程醒来。如果要在一个管道上复用信号,请将信号编号或其他ID写入管道。

答案 1 :(得分:1)

您应该使用类似pthreads的POSIX线程库。它不仅提供线程本身,还提供基本同步原语,如互斥(锁),条件,信号量。这是我发现的一个教程似乎很不错: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

对于它的价值,如果你对多线程编程完全不熟悉,如果你知道其中任何一个,那么用Java或Python学习它可能会容易一些。

答案 2 :(得分:1)

我认为解决问题的常用方法是让信号处理程序只做很少量的工作。例如。设置一些timer_expired标志。然后你有一些线程定期检查标志是否已设置,并进行实际工作。

如果您不想使用信号,我认为您必须让线程休眠或忙碌 - 等待指定的时间。

答案 3 :(得分:0)

使用Posix间隔计时器,并通过信号通知它。在信号处理函数内部,几乎没有C函数,如printf()可以使用,因为它们不是可重入的。

使用单个全局标志,声明为静态易失性 ,供您处理信号处理程序。处理程序应该字面上有这一行代码,而不是其他代码;该标志应该影响1& 1中其他地方的流量控制。只有程序中的线程。

static volatile bool g_zig_instead_of_zag_flg = false;
...
void signal_handler_fnc()
     g_zig_instead_of_zag_flg = true;
return

int main() {

   if(false == g_zig_instead_of_zag) {
      do_zag();
   }  else  {
      do_zig();
      g_zig_instead_of_zag = false;
    return 0;
}

Michael Kerrisk的 Linux编程接口 has examples两种方法,还有一些,但这些示例附带了很多自己的私有函数你必须开始工作,这些例子小心地避免了他们应该探索的许多问题,所以不是很好。

使用通过线程通知的Poxix间隔计时器会使事情变得更糟,而AFAICT,这种通知方法几乎没用。我只是说了很多,因为我允许在main()线程中没有做任何事情,并且处理程序线程中的所有内容都很有用,但我肯定不会想到任何这种情况。