【问题标题】:How do I make a Posix thread finish its job after a certain amount of time?如何让 Posix 线程在一定时间后完成其工作?
【发布时间】:2015-07-09 10:44:11
【问题描述】:

我想让 Posix 线程在经过一定时间后完成其工作。您可以在简单的 C + Python 伪代码中看到我的解决方案。但我认为这不是一个有效和准确的解决方案。实现这一目标的最佳方法是什么?

Mutex incrementLock
BigInteger n = 0
int milliToWork = 5000

Worker()
    int elapsedMilli = 0
    while elapsedMilli < milliToWork
        clock_t startClock = clock()
        Lock(incrementLock)
        n += 1
        Unlock(incrementLock)
        clock_t endClock = clock()
        elapsedMilli += (double)(endClock - startClock) / (double)CLOCKS_PER_SEC * 1000.0

main()
    int nThreads = 100
    Thread threads[nThreads]
    for i = 1 to nThreads
        ThreadCreate(threads[i], Worker)
    for i = 1 to nThreads
        ThreadJoin(threads[i])

【问题讨论】:

  • 这取决于“它的工作”是什么。如果要尽可能快地增加n,那么您所拥有的就可以了。
  • @D.Shawley 好吧,我需要生成几个线程,让它们一起做一些计算,这必须在一定时间内完成,比如 30 秒。所以他们应该在例如 28 秒内尽力而为,最后 2 秒是一些清理工作。我的解决方案是否足够准确地测量时间来做到这一点?
  • 是的。 IIRC,CLOCKS_PER_SEC 被 POSIX 要求为 1,000,000,所以它应该更准确。

标签: c multithreading pthreads


【解决方案1】:

您可以设置一个计时器,以便在您的时间到时向您发送信号。伪代码:

sig_action_handler()
{
  /*cleanup*/
  pthread_exit();
}

worker()
{
  sigaction(sig_action_handler);
  timer_create();
  timer_settime();
  while(true)
    {
      /*do work*/
    }
 }

或者,为了更容易穿线:

sig_action_handler(int, siginfo_t *t, void *)
{
  volatile sig_atomic_t *at = t->si_value.sival_ptr;
  *at = true;
}

worker()
{
  volatile sig_atomic_t at = 0;
  struct sigevent si = {/*...*/, .sigev_value.sival_ptr = &at};
  sigaction(sig_action_handler);
  timer_create(/*...*/, &si, /*...*/);
  timer_settime();
  while(!at)
    {
      /*do work*/
    }
  /*cleanup*/
 }

【讨论】:

  • 同意。但需要注意的是,随时中止“工作”是安全/可取的。
  • @AlanAu:或者,您可以有一个在循环中测试并由信号处理程序设置的volatile sig_atomic_t。这样就可以在信号处理程序上下文之外,在普通代码中完成清理工作。
  • 再次同意。但这取决于超时的粒度(秒、微秒等)与实际工作的时间。例如,如果超时以秒为单位,工作以毫秒或微秒为单位,那么 OP 当前的解决方案可能就足够了,而且更简单一些。
  • @AlanAu:嗯,我发现这种计时器使用起来非常简单。不过,我对混合信号和线程有点警惕。
  • 是的。我的意思是信号和线程方面,而不是计时器本身。特别是在这种有多个线程的情况下。例如,如果每个线程需要不同的工作超时,则计时器解决方案将不起作用(或需要信号/线程/同步体操)。因为信号可以传递给任何线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
相关资源
最近更新 更多