C 如何使用带有sigint的标志通知何时';他在一秒钟内被发送了两次?

C 如何使用带有sigint的标志通知何时';他在一秒钟内被发送了两次?,c,flags,sigint,C,Flags,Sigint,我是c语言编程的新手,正在努力完成一项任务。代码的基础是有一个1秒的计时器(我使用的是sleep(1)),它以1的增量开始计数。每次发送sigINT时,我将增量增加1,计数器打印出新的数字。我用sigterm来减少这个数字。所有这些都很好 最后一部分是,如果我在一秒钟内使用sigINT两次,那么就终止程序。我尝试过使用一个“标志”来执行此操作,该标志对我来说设置为0。调用sigINT时,将其增加1。在我的while循环中将其重置为0。我试着写一个if语句,如果增量大于1,程序就会停止。但是,如果

我是c语言编程的新手,正在努力完成一项任务。代码的基础是有一个1秒的计时器(我使用的是sleep(1)),它以1的增量开始计数。每次发送sigINT时,我将增量增加1,计数器打印出新的数字。我用sigterm来减少这个数字。所有这些都很好

最后一部分是,如果我在一秒钟内使用sigINT两次,那么就终止程序。我尝试过使用一个“标志”来执行此操作,该标志对我来说设置为0。调用sigINT时,将其增加1。在我的while循环中将其重置为0。我试着写一个if语句,如果增量大于1,程序就会停止。但是,如果在此之后使用sleep(0)和flag=0,我永远无法使flag大于1。我知道这可能不是最好的解决方法,但我没有运气找到更好的解决方案。感谢您的帮助。谢谢

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

int inc = 1;
int flag = 0;

void handle_sigint(int sig_num)
{
    signal(SIGINT, handle_sigint);
    if (inc < 10)
    {
        inc++;
    }
    flag++;
    printf("\nflag=%d\n", flag);
    printf("\nSIGINT received: Increment is now %d\n", inc);
    fflush(stdout);
}

void handle_sigterm(int sig_num)
{
    signal(SIGTERM, handle_sigterm);
    if (inc > 0)
    {
        inc--;
    }
    printf("\nSIGTERM received: Increment is now %d\n", inc);
    fflush(stdout);
}

int main()
{
    int num = 0;
    signal(SIGINT, handle_sigint);
    signal(SIGTERM, handle_sigterm);
    printf("Process ID: %d\n", getpid());
    while (1)
    {
        if (flag > 1)
        {
            pid_t iPid = getpid();
            printf("\nExiting the program now\n"); 
            kill(iPid, SIGKILL);
        }   
        printf("%d\n", num);
        num = num + inc;
        sleep(1);
        flag = 0;
    }
    return 0;
}
#包括
#包括
#包括
int inc=1;
int标志=0;
无效句柄\u sigint(int sig\u num)
{
信号(SIGINT,句柄\ SIGINT);
如果(inc<10)
{
inc++;
}
flag++;
printf(“\nflag=%d\n”,标志);
printf(“\n收到的初始值:增量现在是%d\n”,inc);
fflush(stdout);
}
无效句柄\u sigterm(int sig\u num)
{
信号(SIGTERM,句柄\ SIGTERM);
如果(inc>0)
{
公司--;
}
printf(“\n收到的术语:增量现在是%d\n”,inc);
fflush(stdout);
}
int main()
{
int num=0;
信号(SIGINT,句柄\ SIGINT);
信号(SIGTERM,句柄\ SIGTERM);
printf(“进程ID:%d\n”,getpid());
而(1)
{
如果(标志>1)
{
pid_t iPid=getpid();
printf(“\n正在安装程序\n”);
kill(iPid,SIGKILL);
}   
printf(“%d\n”,num);
num=num+inc;
睡眠(1);
flag=0;
}
返回0;
}

如果正在设置
flag=0
就在
睡眠(1)
之后,在检查
If(flag>1)
之前。这意味着将其设置为零和检查之间没有时间,在这段时间内,您希望向程序发送到SIGINT信号。检查后,您已将该标志最多设置为零

sleep()
呼叫是可中断的!如果
sleep()
被信号中断,它将返回剩余的睡眠秒数。参考阅读
人工睡眠
。由于“1秒”实际上不能被较小的数据块整除,因此可以使用
usleep
或只使用
nanosleep
调用
nanosleep
返回
-1
并将
errno
设置为
EINTR
,前提是在睡眠期间接收到信号。因为它在第二个参数中返回剩余的睡眠时间,所以很容易使用它进行循环。您必须为
错误添加
#包含
,为
纳米睡眠添加
#包含

因此,接下来的事情是:

while (1) {
   if (flag > 1) {
          // some code
   }
   // printf("something");

   // set flag before sleeping!
   flag = 0; 

   // wait a second
   struct timespec rqtp = { 1, 0 };
   while (nanosleep(&rqtp, &rqtp) == -1 && errno == EINTR) {
       // repeat until we slept a full second
   }

}
注:

  • 好代码!请遵循缩进样式并缩进代码。我推荐
  • printf
    fflush
    不是信号安全功能。从信号处理程序调用它们是未定义的行为。您不应该从信号处理程序调用
    printf
  • 从技术上讲,应使用volatile sig_atomic_t
类型与信号处理程序同步。我想最好将
标志
inc
变量至少标记为
volatile

请缩进您的代码。那么,如果您在睡眠(1)
之后立即设置
flag=0
,那么在
if(flag>1)
中,
标志将永远不会是1。在设置
flag=0
和检查它之间,您必须发送两个SIGINT。一种可能是在信号处理程序中使用高分辨率计时器,如
clock_gettime()
,并将最后一次中断的时间保留在某个位置,然后比较新时间和旧时间,以查看差异是否小于1秒(如果不是的话,记得把新的时间保存在旧的时间里)。因为你已经滥用了关于时间的规则,这不会引起任何额外的悲伤。事实上,
clock_gettime()
是明确允许的,而
printf()
fflush()
则不允许。建议使用
setitimer()
并与生成1秒间隔相关:为了便于阅读和理解:1)请始终缩进代码。在每个左大括号“{”之后缩进。在每个右大括号“}”之前取消缩进。建议每个缩进级别为4个空格。2) 单独的代码块:
用于
如果
其他
执行时…当
切换
案例
默认值
通过一个空行关于:
睡眠(1);flag=0对于所述目标,这些顺序错误。建议放置
标志=0sleep()
之前,code>非常感谢!这很有效。我也记下了你对其他改进的意见。