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

how to run that timer task continuously?

本文关键字:运行 计时器 任务 连续 何连续      更新时间:2023-10-16
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 coden");
    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 地址和端口号接收来自客户端的请求。服务器正在等待来自客户端的请求,并将响应发送回客户端。当它从客户端接收数据时,它应该调用计时器任务(即在我的代码中调用BackTimers),为此我还创建了计时器,每 2 毫秒、10 毫秒和 100 毫秒调用一次任务。

我的问题:在调试模式下 - 控件正在到达 maketimer 函数调用,但它没有自动运行(我没有添加任何断点)。 它在 maketimer3 处停止。如何让它在不停止的情况下运行??

正如我在你之前的问题中回答的那样,这可能与你的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);;应该做什么。 我理解你一定感到沮丧,但这正在成为一个移动的目标。

这是一个匆忙(但我认为准确)的切碎版本的代码。 由于您在CreateSocket while(1);,它只会创建 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 1n");}
void TASK2() {printf("task 2n");}
void TASK3() {printf("task 3n");}

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 个计时器。 如果您只希望它们在每个套接字读取中关闭一次,那么要么没有间隔值,这样它们就不会重复关闭,或者在它们第一次关闭后重置计时器(即将值/间隔值归零)。 但无论哪种情况,您都应该重用它们。