c++ - 如果我使用 scanf 程序终止

标签 c++ c linux timer

我正在尝试在代码中实现计时器,我发现的所有示例都使用 while(1)for(;;) 但是当我尝试使用使用 scanf 我的程序终止。它是否在 stdin 上获得任何值,因为如果我使用 scanf 两次,那么在退出程序之前会调用两次计时器。 这是我的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <signal.h>
#include <time.h>

#include <linux/socket.h>
#include <time.h>


#define SIGTIMER (SIGRTMAX)
#define SIG SIGUSR1
static timer_t     tid;
static timer_t     tid2;

void SignalHandler(int, siginfo_t*, void* );
timer_t SetTimer(int, int);

int main(int argc, char *argv[]) {

    int t;

    printf("SIGRTMAX %d\n", SIGRTMAX);
        printf("SIGRTMIN %d\n", SIGRTMIN);

    struct sigaction sigact;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = SA_SIGINFO;
    sigact.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIGTIMER, &sigact, NULL) == -1) {
        perror("sigaction failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sigact, NULL);
    tid=SetTimer(SIGTIMER, 1000);

    struct sigaction sa;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIG, &sa, NULL) == -1) {
        perror("sa failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sa, NULL);
    tid2=SetTimer(SIG, 1000);

   // for(;;);  or while(1) Working properly

    scanf("%d", &t); /// Program terminates
    return 0;
}

void SignalHandler(int signo, siginfo_t* info, void* context)
{


    if (signo == SIGTIMER) {
        printf("Command Caller has ticked\n");

    }else if (signo == SIG) {
        printf("Data Caller has ticked\n");

    } else if (signo == SIGINT) {
        timer_delete(tid);
        perror("Crtl+c cached!");
        exit(1);  // exit if CRTL/C is issued
    }
}
timer_t SetTimer(int signo, int sec)
{
    static struct sigevent sigev;
    static timer_t tid;
    static struct itimerspec itval;
    static struct itimerspec oitval;

    // Create the POSIX timer to generate signo
    sigev.sigev_notify = SIGEV_SIGNAL;
    sigev.sigev_signo = signo;
    sigev.sigev_value.sival_ptr = &tid;

    if (timer_create(CLOCK_REALTIME, &sigev, &tid) == 0)
    {

        itval.it_value.tv_sec = sec / 1000;
        itval.it_value.tv_nsec = (long)(sec % 1000) * (1000000L);
        itval.it_interval.tv_sec = itval.it_value.tv_sec;
        itval.it_interval.tv_nsec = itval.it_value.tv_nsec;



        if (timer_settime(tid, 0, &itval, &oitval) != 0)
        {
            perror("time_settime error!");
        }
    }
    else
    {
        perror("timer_create error!");
        return NULL;
    }
    return tid;
}

那么,我该如何解决这个问题呢? 任何帮助,将不胜感激。 谢谢,Yuvi

最佳答案

信号中断scanf。如果在 scanf 输出之后添加 perror('scanf') 将是:

SIGRTMAX 64
SIGRTMIN 34
Command Caller has ticked
Data Caller has ticked
scanf: Interrupted system call

如果将 scanf 替换为:

do {
    errno = 0;
    scanf("%d", &t);
} while(errno == EINTR);

当 scanf 失败并返回 Interrupted system call 时将重试。

关于c++ - 如果我使用 scanf 程序终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10086760/

相关文章:

c - 在内核中访问用户空间结构的成员给出了错误的值

c# - Encoding.utf8 将逗号转换为 C# 中的某些特殊字符

c++ - 如何正确地创建(和分配)仅由 C++ 中的抽象基已知的对象列表?

c - 如何正确确定我的客户端是否仍然连接到使用 C 套接字的服务器?

c - setcontext 中的段错误

linux - 在bash中用另一个数字替换一个数字

c++ - 使用 std::type_info 在 natvis 中进行转换

c++ - 从 std::string C++ 中提取任意数据值

c - 如何使用 for 循环找到 x 次幂 n 直到用户不想退出

c++ - C/C++ 中的 Aho-Corasick 算法(十六进制)