【问题标题】:pthread time-out or cancel, using pthread_cond_timedwait, or what?pthread 超时或取消,使用 pthread_cond_timedwait,还是什么?
【发布时间】:2014-04-14 00:59:47
【问题描述】:

我有一个线程在消息队列上等待(阻塞)以处理要处理的消息。 轮询不是一种选择。

当某个 START 消息到达时,我们设置一些变量,然后必须在给定时间延迟后重置,或者在另一个 STOP 消息到达时重置。如果已设置,重复的 START 应将设置时间延长给定的时间段(可以重新开始)。

同时,线程应该继续处理其他到达的消息。

在我看来,这样做的方法是生成并分离一个新的 pthread 来处理超时。此线程将超时并在退出前向父线程发送 STOP 消息,或者如果父线程收到 STOP 消息,则被提前终止/取消。

我一直在阅读 pthreads 文档,但我并不完全清楚最好的方法:

  1. 我可以创建一个只休眠给定时间的线程,然后 发送 STOP 消息,如果 STOP 则发送 pthread_cancel() 消息更快到达。文档中似乎暗示(但未明确说明),在这种情况下,“取消”操作基本上会在睡眠中终止线程,没有进一步的操作。

  2. 我可以创建一个线程,它使用 pthread_cond_timedwait() 来等待某个条件,如 this 示例。这看起来最“合适”,但也最麻烦。

  3. 类似于 1 的东西,但是 fork() 一个进程,它监视一个标志变量,如果标志被重置,要么超时要么放弃。

  4. 使用 SIGALARM 处理程序,加上 Alarm() 来设置/取消设置定时信号(听起来很简单,但实践起来似乎有点不整洁,你只能有一个警报)

延迟在秒范围内,精确到 ~0.1 秒会很好。我不喜欢 pthread_cond_timedwait 使用绝对时间的方式,因为用户可能会设置时钟并将事情搞砸(不是世界末日,但对我来说似乎不是最佳选择)。

从网上的示例中我不清楚“pthread_cancel”或“pthread_cond_timedwait”对于分离的线程是否工作/干净

我不会发布我当前喜欢的选项的代码,因为它几乎是选项 2 中 example 的复制粘贴。

【问题讨论】:

  • 在您的平台上可以选择消息队列吗?如果是这样,选择适当的超时似乎是一个可行的选择。
  • 如果没有消息到达,我不会尝试超时,我会尝试设置一个变量,如果没有以其他方式更改,该变量将在一段时间后重置。在此期间,消息队列将忙于其他来回消息。

标签: c multithreading pthreads posix delay


【解决方案1】:

我看不出你在苦恼什么。据我了解你的描述,定时器显然是要走的路。

  • 使用timer_create 创建一个计时器,以便在时间过去时发送信号。如果您所做的只是设置一个开关变量,这很容易在信号处理程序本身中完成
  • 如果在剩余时间时收到 STOP 消息,请使用 timer_settime 解除计时器
  • 如果您在计时器布防时收到第二个 START 消息,请使用 timer_gettime 获取计时器上的剩余时间,添加新的时间量,然后使用 timer_settime 重置计时器。
  • 使用 timer_delete 删除计时器

alarmitimer 间隔计时器不同,您不限于单个计时器。

顺便说一句,如果您使用的是 POSIX 消息队列并且您的消息很少而且相距甚远,那么可能值得使用mq_notify。除了整天阻塞mq_receive,您可以将其设置为每当有新消息放入先前为空的队列时启动一个线程,您只需处理任何和所有消息,直到队列再次为空并且线程结束。

【讨论】:

  • 我忘了添加我对 linux 开发经验不是很丰富的免责声明,我已经陷入了困境,所以不知道计时器功能。但你是对的,它们看起来确实很像我所追求的那种东西。现在 R'ing TFM...
  • @John U,如果您使用的是 linux 或一些支持它的衍生产品,请查看timerfd 工具。这使您可以同时使用selectpoll 来监控您的信号到期和(因为posix MQ 的mqd_t 类型是Linux 上的文件描述符)您的队列,而无需处理处理程序的麻烦。跨度>
猜你喜欢
  • 2014-06-06
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 2017-03-02
相关资源
最近更新 更多