在linux环境中,如何实现多线程中使用多个定时器,POSIX定时器可以吗,如何用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在linux环境中,如何实现多线程中使用多个定时器,POSIX定时器可以吗,如何用?相关的知识,希望对你有一定的参考价值。

参考技术A 个人解决了,以下是一个实现:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <time.h>

#if 1
pthread_attr_t attr;
timer_t hard_timer, software_timer;
struct sigevent hard_evp, software_evp;

static void watchdog_hard_timeout(union sigval v)

time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;

time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog hard timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);

q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;

ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0)
printf("settime err(%d)!\n", ret);



static void watchdog_software_timeout(union sigval v)

time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;

time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog software timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);

q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 10;
ts.it_value.tv_nsec = 0;

ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0)
printf("settime err(%d)!\n", ret);



static void dcmi_sol_pthread_attr_destroy(pthread_attr_t *attr)

pthread_attr_destroy(attr);


static int dcmi_sol_pthread_attr_init(pthread_attr_t *attr)

int ret;

if ((ret = pthread_attr_init(attr) != 0))
goto err;

if ((ret = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)) != 0)
dcmi_sol_pthread_attr_destroy(attr);
goto err;

/* 设置线程的栈大小,失败则用系统默认值 */
pthread_attr_setstacksize(attr, 128 * 1024);

return 0;
err:
printf("set ptread attr failed(ret:%d)!\n", ret);
return -1;


int main(void)

struct itimerspec ts;
int ret;

ret = dcmi_sol_pthread_attr_init(&attr);
if (ret != 0)
printf("init pthread attributes fail(%d)!\n", ret);
exit(-1);


memset(&hard_evp, 0, sizeof(struct sigevent));
hard_evp.sigev_value.sival_ptr = &hard_timer;
hard_evp.sigev_notify = SIGEV_THREAD;
hard_evp.sigev_notify_function = watchdog_hard_timeout;
hard_evp.sigev_notify_attributes = NULL;//&attr;

memset(&software_evp, 0, sizeof(struct sigevent));
software_evp.sigev_value.sival_ptr = &software_timer;
software_evp.sigev_notify = SIGEV_THREAD;
software_evp.sigev_notify_function = watchdog_software_timeout;
software_evp.sigev_notify_attributes = NULL;//&attr;

ret = timer_create(CLOCK_REALTIME, &hard_evp, &hard_timer);
if(ret != 0)
perror("hard timer_create fail!");
exit(-1);

ret = timer_create(CLOCK_REALTIME, &software_evp, &software_timer);
if (ret != 0)
timer_delete(hard_timer);
perror("software timer_create fail!");
exit(-1);


ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;

ret = timer_settime(hard_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0)
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);


ts.it_value.tv_sec = 10;
ret = timer_settime(software_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0)
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);


while(1)
printf("main ready sleep!\n");
sleep(15);
printf("main sleep finish!\n");


return 0;

#endif本回答被提问者和网友采纳

C#如何在BackgroundWorker 后台线程中使用定时器?

就是说我有一项任务要用BackgroundWorker来进行异步操作,并且需要定时进行,由于定时时间比较短,只有1秒钟,所以不能使用System.Windows.Forms名字空间中的Timer来定时执行,因为它是主线程的定时器,每秒执行一次异步操作,会导致窗体反应迟钝甚至出现未响应的情况,而其他Timer怎么用呢?捣鼓好多天了都不行,那位C#高手帮帮忙,给100分

实际上,Timer并不只有你说的System.Windows.Forms.Timer一种。这个东西作为一个主线程(即UI线程)的控件,它的执行都会在UI线程,当然会造成线程阻塞,也就是你说的窗体未响应。
你可以尝试使用System.Threading.Timer,它可以实现控件Timer的一切功能。另外,和你说的System.Widnows.Forms.Timer不一样的是,它可以定义在非主线程中,当然它的定时执行方法也就不会影响到主线程了。
使用方法如下。
System.Threading.Timer timer = new System.Threading.Timer();//初始化
timer.Interval = 1000; //定时间隔1000ms
timer.Elapsed+=new EventHandler(timer_Elapsed);

private void timer_Elapsed()

//这里的代码每隔1秒时间就会运行,写你定时执行的事件即可
//并且,每次代码执行到这里,其实.NET内部都是用新的线程来处理这部分代码的


你将上面的东西封装成一个方法,注册到BackgroundWorker中,UI就不会假死的。

实际上,要在UI上定时调用异步,并且解决UI的假死,还有其他的方法,BackgroundWorker并不是唯一的选择。
参考技术A Timer会导致窗体反应异常?
可能是你代码的问题吧?
你把代码给我看看?

其它的Timer跟Forms的Timer其实基本差不多
你也可以尝试用Thread执行一个无限循环的方法,比如:
while(true)
做事的代码
Thread.Sleep(1000);// 休眠一秒
本回答被提问者采纳

以上是关于在linux环境中,如何实现多线程中使用多个定时器,POSIX定时器可以吗,如何用?的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot多线程环境下,解决多个定时器冲突问题

SpringBoot多线程环境下,解决多个定时器冲突问题

C语言 用定时器 模拟多线程

多线程 如何自己实现定时器

多线程编程之Linux环境下的多线程

java多线程实现定时器任务