在定时器回调函数中运行其他回调函数是可能出现的情况。如果定时器回调函数执行时间过长,直到下一个定时器事件到来之前仍未结束,这时其他回调函数可能会在该定时器回调函数执行期间被触发并运行。
这种情况下,可以通过在定时器回调函数中使用信号量或互斥锁来保证同步。例如,在定时器回调函数开始运行时获取一个互斥锁,在函数结束后释放该锁,这样其他回调函数就可以在获取该锁之前等待,保证同步执行。
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mutex; // 定义互斥锁
void timer_callback_50ms(union sigval v)
{
pthread_mutex_lock(&mutex); // 获取互斥锁
struct timeval time;
unsigned long long StartTime= 0;
unsigned long long EndTime= 0;
gettimeofday(&time,NULL);
StartTime = ((time.tv_sec*1000000+time.tv_usec));/*unit us*/
printf("fusion:%lld\n",StartTime);
pthread_mutex_unlock(&mutex); // 释放互斥锁
}
void timer_callback_10ms(union sigval v)
{
pthread_mutex_lock(&mutex); // 获取互斥锁
struct timeval time;
unsigned long long StartTime= 0;
unsigned long long EndTime= 0;
gettimeofday(&time,NULL);
StartTime = ((time.tv_sec*1000000+time.tv_usec));/*unit us*/
printf("ipc: %lld\n",StartTime);
pthread_mutex_unlock(&mutex); // 释放互斥锁
}
int main()
{
timer_t timer_fusion;
timer_t timer_ipc;
struct sigevent fusion;
struct sigevent ipc;
struct itimerspec its_fusion;
struct itimerspec its_ipc;
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
int ret = 0;
// Set up signal event
fusion.sigev_notify = SIGEV_THREAD;
fusion.sigev_value.sival_ptr = &timer_fusion;
fusion._sigev_un._sigev_thread._function = (void*)timer_callback_50ms;
fusion._sigev_un._sigev_thread._attribute = NULL;
ipc.sigev_notify = SIGEV_THREAD;
ipc.sigev_value.sival_ptr = &timer_ipc;
ipc._sigev_un._sigev_thread._function = (void*)timer_callback_10ms;
ipc._sigev_un._sigev_thread._attribute = NULL;
// Create the timer
ret = timer_create(CLOCK_REALTIME, &fusion, &timer_fusion);
if( ret == 0)
printf("timer_fusion_create ok\n");
ret = timer_create(CLOCK_REALTIME, &ipc, &timer_ipc);
if( ret == 0)
printf("timer_ipc_create ok\n");
// Set the timer to expire after 50ms
its_fusion.it_value.tv_sec = 0;
its_fusion.it_value.tv_nsec = 50000000;
its_fusion.it_interval.tv_sec = its_fusion.it_value.tv_sec;
its_fusion.it_interval.tv_nsec = its_fusion.it_value.tv_nsec;
its_ipc.it_value.tv_sec = 0;
its_ipc.it_value.tv_nsec = 10000000;
its_ipc.it_interval.tv_sec = its_ipc.it_value.tv_sec;
its_ipc.it_interval.tv_nsec = its_ipc.it_value.tv_nsec;
// Start the timer
ret = timer_settime(timer_fusion, 0, &its_fusion, NULL);
if( ret ==0)
printf("timer_fusion_settime ok\n");
ret = timer_settime(timer_ipc, 0, &its_ipc, NULL);
if( ret ==0)
printf("timer_ipc_settime ok\n");
while(1){
sleep(1);
}
pthread_mutex_destroy(&mutex); // 销毁互斥锁
return 0;
}