Linux计时器是一个过程

时间:2013-04-11 18:04:14

标签: c linux multithreading timer

我正在尝试了解linux中的计时器,以便在我的应用程序中使用它,我从多个来源收集代码并制作了以下程序

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;


void *print_message_function( void *ptr );
static void handler(int sig, siginfo_t *si, void *uc)
{

  pthread_mutex_lock( &mutex1 );
  printf("Caught signal %d from timer\n", sig);
  //it will be working like this in real application
  // 1. check the front of the queue, if timeout then detete it from queue 

  pthread_mutex_unlock( &mutex1 );


}

int main(int argc, char *argv[])
{
  struct sigevent sev;
  struct itimerspec its;
  long long freq_nanosecs;
  sigset_t mask;
  struct sigaction sa;

  printf("Establishing handler for signal %d\n", SIG);
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = handler;
  sigemptyset(&sa.sa_mask);
  sigaction(SIG, &sa, NULL);

  sev.sigev_notify = SIGEV_SIGNAL;
  sev.sigev_signo = SIG;
  sev.sigev_value.sival_ptr = &timerid;
  timer_create(CLOCKID, &sev, &timerid);
  /* Start the timer */

  its.it_value.tv_sec = 1;
  its.it_value.tv_nsec = 0;
  its.it_interval.tv_sec = its.it_value.tv_sec;
  its.it_interval.tv_nsec = its.it_value.tv_nsec;

  timer_settime(timerid, 0, &its, NULL);


  pthread_t thread1, thread2;
  char *message1 = "Thread 1";
  int  iret1 ;

  /* Create independent threads each of which will execute function */

  iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

  pthread_join( thread1, NULL);

  printf("Thread 1 returns: %d\n",iret1);
   exit(0);
}


void *print_message_function( void *ptr )
{
  char *message;
  message = (char *) ptr;
  int i;
  for(i=0;; i++){
    pthread_mutex_lock( &mutex1 );
    printf("%s \n", message);
      //it will be working like this in real application
      // 1. check if a response received from the network 
      // 2. if received then delete from queue 

    pthread_mutex_unlock( &mutex1 );
    usleep(50022);
  }
  pause();
}

我正在尝试检测临界区,在这种情况下是printf,这里的printf只是一个例子,在我的应用程序中它实际上是一个队列,所以线程将一直在printf上工作,当计时器准备就绪时,它必须锁定互斥锁然后打印,上面是正确的方法吗? 在实际应用程序中,线程将等待响应,当其他应用程序收到响应然后我将访问队列时,计时器将始终在特定时间间隔(例如每2秒)检查队列以查看时间消息,如果找到则删除它。

1 个答案:

答案 0 :(得分:1)

不,这不是正确的方法。它只允许从单一处理程序调用异步信号安全函数。否则行为未定义:

  

«处理时,信号处理函数必须非常小心   其他地方可能会在执行中的某个任意点中断   该计划。 POSIX具有“安全功能”的概念。如果有信号   中断不安全函数的执行,并且处理程序调用   不安全的函数,那么程序的行为是不确定的。»

有关详细信息,请参阅man 7 signal

如果您是为Linux编写的,请考虑使用signalfd。其他操作系统也有类似的选择。长话故事,请参阅«How Not To Write a Signal Handler»。

希望它有所帮助。祝你好运!