多线程程序的 C++ 定时器中断
Posted
技术标签:
【中文标题】多线程程序的 C++ 定时器中断【英文标题】:C++ timer interrupt for multithreaded program 【发布时间】:2017-12-13 00:44:43 【问题描述】:我正在 Linux 环境中进行开发。假设我有 3 个线程,t1、t2 和 t3 在我的软件中运行(使用 pthread 实现)。线程 t1 和 t2 没有交错的执行时间在 50ms 到 100ms 之间。无论如何我可以实现线程 t3 以便它每 30 毫秒发出一次中断(即在 t3 完成执行 [sched_yeild()] 后,下一次运行将在 30 毫秒后从该点开始,当 30 毫秒超时时,它将产生它正在运行的任何线程并运行线程 t3 直到它完成[sched_yeild()])?以下是我的代码结构:
#include <pthread.h>
#include <sched.h>
//others header files
void* thread1(void *)
while(1)
//code for thread1 :loop time about 50ms-100ms
sched_yield();
void* thread2(void *)
while(1)
//code for thread2:loop time about 50ms-100ms
sched_yield();
void* thread3(void *)
while(1)
//code for thread3
sched_yield();
int main()
pthread_t t1,t2,t3;
pthread_create(&t1,NULL,thread1,NULL);
pthread_create(&t2,NULL,thread2,NULL);
pthread_create(&t3,NULL,thread3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 0;
【问题讨论】:
您希望 T3 (尽可能接近)立即抢占 T1 和 T2 并运行直到它投降?听起来你想给 T3 更高的优先级。但不要指望这个同步。 定义“中断”的含义。在这种情况下,该术语具有许多不同的含义。此外,您确实了解sched_yield()
不提供任何形式的保证,无论如何,实际会发生什么。这听起来像是一个 XY 问题。你真正的问题是别的东西,你认为解决方案就是这个问题所描述的。也许如果你描述了真正的问题,有人可以为你想出一个真正的解决方案。
@user4581301 是的。在这种情况下,优先级不应该起作用,因为当前正在运行的线程(t1 和 t2)仍在执行并且没有放弃资源。
@SamVarshavchik 抱歉不清楚。在这种情况下,我的意思是,每当 30ms 定时器超时时,它都会发出一个信号,使任何正在运行的线程都会放弃 CPU 资源(抢占)并让 T3 立即运行(T3 有点像中断服务常规)。我的实际问题是我正在从线程 T3 捕获图像,并且我想要一个固定的帧速率。因此我需要 T3 定期运行。
这样的东西更类似于实时操作系统,而不是通用的 Linux。 Linux 内核有实时扩展,这取决于一个可能或可能不可用的发行版。但同样:这是一个 XY 问题。无论真正的问题是什么,尝试解决真正的问题而不是解决 XY 问题更有可能更有成效。可以说,在现有的 Linux 操作系统中,没有任何东西可以用来保证任何此类事情。
【参考方案1】:
您可以让 T3 以高优先级运行(例如,通过 sched_setscheduler(0, SCHED_RR, ...),您可以让 T3 在一个循环中运行,该循环调用 usleep() 休眠一段时间,然后当 usleep() 返回时,T3 可以在再次调用 usleep() 之前做一些有用的事情。如果你想变得聪明,你甚至可以让 T3 改变它传递给 usleep() 的值来弥补 T3 花费的时间(做某事有用)之间的usleep()调用以纠正漂移,因此(有用的东西)更接近每30毫秒(平均)发生一次。
但是,如果您希望 T3 的行为能够以某种方式控制 T1 和 T2 的执行方式/时间,那么您将会失望。默认情况下,线程本质上相对于彼此异步(且不可预测地)执行,仅仅因为 T3 在给定时刻运行并不意味着 T1 和 T2 不在同一时刻运行(想想多核/多处理器)。
如果您尝试同步线程的执行,那么您需要使用适当的线程同步机制,例如互斥锁或条件变量。真的没有替代品。 :)
【讨论】:
以上是关于多线程程序的 C++ 定时器中断的主要内容,如果未能解决你的问题,请参考以下文章