如何连续运行该计时器任务?

时间:2014-02-28 12:06:54

标签: c++ c linux timer handler

static void timerHandler(int sig, siginfo_t *si, void *uc)
{
  timer_t *tidp;

  tidp = si->si_value.sival_ptr;

  if (*tidp == firstTimerID)

    TASK1(Task2ms_Raster);
  else if (*tidp == secondTimerID)
    TASK2(Task10ms_Raster);
  else if (*tidp == thirdTimerID)
    TASK3(Task100ms_Raster);
}

static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS)
{
  //sigset_t mask;
  struct sigevent te;
  struct itimerspec its;
  struct sigaction sa;
  int sigNo = SIGRTMIN;

  /* Set up signal handler. */
  memset(&sa, 0, sizeof(sa));
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = timerHandler;
  sigemptyset(&sa.sa_mask);
  if (sigaction(sigNo, &sa, NULL) == -1)
  {
    perror("sigaction");
  }

  /* Set and enable alarm */
  te.sigev_notify = SIGEV_SIGNAL;
  te.sigev_signo = sigNo;
  te.sigev_value.sival_ptr = timerID;
  timer_create(CLOCK_REALTIME, &te, timerID);

  its.it_interval.tv_sec = 0;
  its.it_interval.tv_nsec = intervalMS * 1000000;
  its.it_value.tv_sec = 0;
  its.it_value.tv_nsec = expireMS * 1000000;
  timer_settime(*timerID, 0, &its, NULL);

  return 1;

}

int CreateSocket()
{

  socklen_t len = sizeof(client);
  // Socket creation for UDP

  acceptSocket = socket(AF_INET, SOCK_DGRAM, 0);

  if (acceptSocket == -1)

  {
    printf("Failure: socket creation is failed, failure code\n");

    return 1;
  }
  else
  {
    printf("Socket started!\n");

  }

  //non blocking mode
  /* rc = ioctl(acceptSocket, FIONBIO, (char *)&flag);
   if (rc < 0)
   {
   printf("\n ioctl() failed \n");
   return 0;
   }*/

  //Bind the socket
  memset(&addr, 0, sizeof(addr));

  addr.sin_family = AF_INET;

  addr.sin_port = htons(port);

  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  rc = bind(acceptSocket, (struct sockaddr*) &addr, sizeof(addr));

  if (rc == -1)
  {
    printf("Failure: listen, failure code:\n");

    return 1;
  }
  else
  {
    printf("Socket an port %d \n", port);

  }

  if (acceptSocket == -1)
  {
    printf("Fehler: accept, fehler code:\n");

    return 1;
  }
  else
  {
    while (rc != -1)
    {

      rc = recvfrom(acceptSocket, buf, 256, 0, (struct sockaddr*) &client,
          &len);
      if (rc == 0)
      {
        printf("Server has no connection..\n");
        break;
      }
      if (rc == -1)
      {
        printf("something went wrong with data %s", strerror(errno));
        break;
      }

      XcpIp_RxCallback((uint16) rc, (uint8*) buf, (uint16) port);
      makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
      makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
      makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms
      while (1)
        ;;

    }
  }

  close(acceptSocket);

  return 0;

}

int main()
{
  Xcp_Initialize();
  CreateSocket();
  return 2;
}

void XcpApp_IpTransmit(uint16 XcpPort, Xcp_StatePtr8 pBytes, uint16 numBytes)
{
  if ((long) XcpPort == port)
  {
    sentbytes = sendto(acceptSocket, (char*) pBytes, (long) numBytes, 0,
        (struct sockaddr*) &client, sizeof(client));
  }
  XcpIp_TxCallback(port, (uint16) sentbytes);
}

我正在研究客户端和服务器架构。服务器代码如上所示,我创建了一个套接字,通过ip地址和端口号从客户端接收请求。服务器正在等待来自客户端的请求并将响应发送回客户端。当它从客户端接收数据时,它应该调用定时器任务(即我的代码中的callBackTimers),为此我还创建了定时器来每2ms,10ms和100ms调用任务。

我的问题:在调试模式下 - 控制正在进入maketimer函数调用,但它没有自动运行(我没有添加任何断点)。它正在停止在maketimer3。如何使它运行而不停止??

2 个答案:

答案 0 :(得分:1)

正如我在previous question中回答的那样,这个可能与您的CreateSocket功能有关,即:

while(rc!=-1)
{
     rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len);
     if(rc==0)
     {
       printf("Server has no connection..\n");
       break;
     }
     if(rc==-1)
     {
         printf("something went wrong with data %s", strerror(errno));
       break;
     }

     XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );

     makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
     makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
     makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms

     while(1)
     ;;
}

您每次通过此循环创建计时器。你永远不会删除它们。您可以创建多少计时器是有限制的。来自man (2) timer_create

  

内核为使用timer_create()创建的每个计时器预分配“排队的实时信号”。因此,定时器的数量受RLIMIT_SIGPENDING资源限制的限制(请参阅setrlimit(2))。

您没有检查timer_create的返回代码状态,我的猜测是您的计时器耗尽,然后才失败。

(顺便说一句,不确定while(1);;应该做什么。我理解你必须感受到的挫败感,但这已成为一个移动目标。)

答案 1 :(得分:0)

这是一个匆忙(但我认为准确)的代码切碎版本。由于while(1);中的CreateSocket,它只会创建3个计时器。如果你运行它,你会看到TASKS1 / 2/3运行。这本身并不是你的问题。

#define _POSIX_C_SOURCE 199309
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>


timer_t firstTimerID, secondTimerID, thirdTimerID;

void TASK1() {printf("task 1\n");}
void TASK2() {printf("task 2\n");}
void TASK3() {printf("task 3\n");}


static void timerHandler(int sig, siginfo_t *si, void *uc)
{
  timer_t *tidp;

  tidp = si->si_value.sival_ptr;

  if (*tidp == firstTimerID)
    TASK1();
  else if (*tidp == secondTimerID)
    TASK2();
  else if (*tidp == thirdTimerID)
    TASK3();
}

static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS)
{
  //sigset_t mask;
  struct sigevent te;
  struct itimerspec its;
  struct sigaction sa;
  int sigNo = SIGRTMIN;

  /* Set up signal handler. */
  memset(&sa, 0, sizeof(sa));
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = timerHandler;
  sigemptyset(&sa.sa_mask);
  if (sigaction(sigNo, &sa, NULL) == -1)
  {
    perror("sigaction");
  }

  /* Set and enable alarm */
  te.sigev_notify = SIGEV_SIGNAL;
  te.sigev_signo = sigNo;
  te.sigev_value.sival_ptr = timerID;
  timer_create(CLOCK_REALTIME, &te, timerID);

  its.it_interval.tv_sec = 0;
  its.it_interval.tv_nsec = intervalMS * 1000000;
  its.it_value.tv_sec = 0;
  its.it_value.tv_nsec = expireMS * 1000000;
  timer_settime(*timerID, 0, &its, NULL);

  return 1;

}

int CreateSocket()
{
    int rc = 5;

    while (rc != -1)
    {
      makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
      makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
      makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms

      while (1);;
    }

  return 0;
}

int main()
{
  CreateSocket();
  return 2;
}

注意循环问题,看看你必须从哪里去。创建3个计时器。如果您只希望它们每个插槽读取一次,那么要么没有间隔值,所以它们不会重复关闭重置定时器(即将值/间隔值清零)他们第一次出发后。但在任何一种情况下,你都应该重复使用它们。