pThread同步问题

2023-12-12

我面临 pthread 同步问题。 threadWaitFunction1,是一个线程等待函数。 我预计行号。第247章flag = 1仅在 243-246 完成后执行。 但我觉得奇怪的是,有时,在243-246还没有完成之前,它就直接跳到247。

请帮我。

提前致谢。

236   struct timespec timeToWait;
237   static void* threadWaitFunction1(void *timeToWaitPtr)
238   {
239       cout << "Setting flag =0 inside threadWaitFunction1\n";
240       
241       cout << "Inside threadWaitFunction\n";
242       struct timespec *ptr = (struct timespec*) timeToWaitPtr;
243       pthread_mutex_lock(&timerMutex);
          flag = 0;
244       pthread_cond_timedwait(&timerCond, &timerMutex, ptr);
          flag=1;
245       pthread_mutex_unlock(&timerMutex);
246       cout << "Setting flag =1 inside threadWaitFunction1\n";
247       
248
249    }

创建并调用上述线程的线程是:

263  static void timer_trackStartTime ()
264  {
265       struct timeval now;
266       pthread_t thread;
267       
268       printf("Inside trackStartTime: flag = %d\n",flag);
269 
270      /* Setting timer expiration */
271       timeToWait.tv_sec = lt_leak_start_sec;;  // First expiry after 1 sec
272       timeToWait.tv_nsec = lt_leak_start_nsec;
273       pthread_create(&thread, NULL, threadWaitFunction1, &timeToWait);
274       pthread_join(thread, NULL);
275       //pthread_kill(thread, SIGKILL); // Destroying the thread to ensure no leaks
276 
.
.
283       }

如果我使用 pthread_mutex_lock 保护整个函数,但仍然存在相同的问题。如何保证有序执行?有人可以帮忙吗?

编辑:now.tv_sec 和 now.tv_nsec 从代码中删除。 *编辑:更改了互斥体内的标志(仍然不起作用)*


所以让你不高兴的并不是真正的执行顺序(这很可能是正确的)而是时间安排。在“它在 243-246 完成之前直接跳转到 247”下,您的意思是“我观察到它在 244 中应该等待的时间过去之前执行了 247”。正确的?

然后,我怀疑这是问题虚假唤醒:即使没有其他线程发出条件变量信号,线程也可能会被唤醒。规格pthread_cond_timedwait()说“可能会发生来自 pthread_cond_timedwait() 或 pthread_cond_wait() 函数的虚假唤醒。”

通常,条件变量与应用程序中的某个事件相关联,等待条件变量的线程实际上是在等待另一个线程发出的表示感兴趣的事件已发生的信号。如果你没有事件,只是想等待一定的时间,确实有其他方式,比如usleep() or timers,更合适,除非您还需要 pthread 取消点。

补充:既然你看起来很满意usleep()并且只问为什么pthread_cond_timedwait()没有达到您的期望,我决定不发布代码。如果您需要它,您可以使用@Hasturkun的答案。


ADDED-2:下面注释中的输出(应用 Hasturkun 的解决方案后获得)表明等待线程不会退出循环,这可能意味着pthread_cond_timedwait()返回与 ETIMEDOUT 不同的内容。您是否看到@nos 对您的帖子的评论(我固定了要减去的纳秒量):

确保 (now.tv_usec * 1000) + lt_leak_start_nsec;不会溢出。您只能将 tv_nsec 设置为最大值 999999999,如果表达式大于该值,您应该从 tv_nsec 中减去 1000000000,然后将 tv_sec 加 1。如果您的 timeToWaitPtr 包含无效的 tv_nsec(大于 999999999),pthread_cond_timedwait 将失败(您应该检查它的返回值也是如此。) – 4 月 28 日 19:04

在这种情况下,pthread_cond_timedwait()会反复返回EINVAL并且永远不会脱离循环。最好在进入等待循环之前调整超时,尽管也可以响应EINVAL.


ADDED-3:现在,在您更改问题中的代码以通过超时而不添加到当前时间后,它还有另一个问题。如中所述the spec,超时为pthread_cond_timedwait()是绝对时间,而不是相对时间;因此,当您传递 3 秒之类的超时值时,它会被解释为“自系统时间参考点起 3 秒”。那一刻几乎肯定已经过去了一段时间了,所以pthread_cond_timedwait()立即返回。
我建议您彻底阅读规范(包括基本原理),以更好地理解该函数的使用方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pThread同步问题 的相关文章

随机推荐