[英]How to use a flag with sigint to notify when it's been sent twice in one second?
我是 C 編程的新手,正在為一項任務而苦苦掙扎。 代碼的基礎是有一個 1 秒的計時器(我正在使用 sleep(1)),它從 1 的增量開始計數。每次我發送 sigINT 時,我將增量增加 1 並且計數器打印出新號碼。 我使用 sigterm 來減少數字。 所有這些都運行良好。
如果我在一秒鍾內使用 sigINT 兩次,最后一部分是終止程序。 我曾嘗試使用對我而言設置為 0 的“標志”來執行此操作。調用 sigINT 時,將其增加 1。在我的 while 循環中將其重置為 0。 我試着寫一個 if 語句,如果增量大於 1,程序就會停止。 但是在此之后使用 sleep(0) 和 flag=0,我永遠無法讓標志大於 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;
}
如果在sleep(1)
和在檢查if(flag>1)
之前設置flag=0
。 這意味着在將其設置為零和檢查之間沒有時間,並且在那個時候您想將 SIGINT 信號發送到您的程序。 在檢查之后,您最多將標志設置為零。
sleep()
調用是可中斷的! 如果sleep()
被信號中斷,則返回睡眠剩余的秒數。 供參考閱讀man sleep
。 由於“1 秒”實際上不能被較小的塊整除,因此您可以使用usleep
或僅使用nanosleep
調用。 如果在睡眠期間收到信號, nanosleep
返回-1
並將errno
為EINTR
。 因為它在第二個參數中返回睡眠剩余的時間,所以很容易用它做一個循環。 您必須為errno
添加#include <errno.h>
,為nanosleep
添加#include <errno.h>
#include <time.h>
。
所以一些東西:
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
類型應該用於與信號處理程序同步。 我想最好將您的flag
和inc
變量至少標記為volatile
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.