C 如何使用带有sigint的标志通知何时';他在一秒钟内被发送了两次?
我是c语言编程的新手,正在努力完成一项任务。代码的基础是有一个1秒的计时器(我使用的是sleep(1)),它以1的增量开始计数。每次发送sigINT时,我将增量增加1,计数器打印出新的数字。我用sigterm来减少这个数字。所有这些都很好 最后一部分是,如果我在一秒钟内使用sigINT两次,那么就终止程序。我尝试过使用一个“标志”来执行此操作,该标志对我来说设置为0。调用sigINT时,将其增加1。在我的while循环中将其重置为0。我试着写一个if语句,如果增量大于1,程序就会停止。但是,如果在此之后使用sleep(0)和flag=0,我永远无法使flag大于1。我知道这可能不是最好的解决方法,但我没有运气找到更好的解决方案。感谢您的帮助。谢谢C 如何使用带有sigint的标志通知何时';他在一秒钟内被发送了两次?,c,flags,sigint,C,Flags,Sigint,我是c语言编程的新手,正在努力完成一项任务。代码的基础是有一个1秒的计时器(我使用的是sleep(1)),它以1的增量开始计数。每次发送sigINT时,我将增量增加1,计数器打印出新的数字。我用sigterm来减少这个数字。所有这些都很好 最后一部分是,如果我在一秒钟内使用sigINT两次,那么就终止程序。我尝试过使用一个“标志”来执行此操作,该标志对我来说设置为0。调用sigINT时,将其增加1。在我的while循环中将其重置为0。我试着写一个if语句,如果增量大于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代码>对于所述目标,这些顺序错误。建议放置标志=0在调用sleep()
之前,code>非常感谢!这很有效。我也记下了你对其他改进的意见。