在没有 SA_RESTART 的情况下使用 sigaction 并防止无限循环

Using sigaction without SA_RESTART and preventing an infinte loop

我有以下代码:

struct sigaction act = {{0}};
act.sa_handler = handler;
sigaction(SIGINT, &act, nullptr);
while (true) 
{
    std::cout << "input:";
    std::getline(std::cin, line);
    // Handle line
}

当我收到 SIGINT 时,程序陷入无限循环。我不能简单地设置 SA_RESTART(比如 ),因为我想在收到信号时打印一条消息。

我不想直接从处理程序中打印,所以我在其中设置了一个标志并在循环中检查它。

if (flag)
    std::count << "got SIGINT" << std::endl;

SA_RESTART 导致 getline 阻塞,所以除非 getline returns,否则我无法到达此 if 并处理信号。反正有这个吗?

编辑(完整示例):

#include <iostream>
#include <signal.h>

bool flag = false;

void handler(int signum)
{
    flag = true;
}

int main()
{

    struct sigaction act = {{0}};
    act.sa_handler = handler;
    //act.sa_flags = SA_RESTART;
    sigaction(SIGINT, &act, nullptr);
    while (true) 
    {
        std::cout << "input:";
        std::string line;
        std::getline(std::cin, line);

        if (flag) {
           std::cout << "got SIGINT" << std::endl;
           flag = false;
        }
    }
}

getline 被中断时,将在 cin 上设置一个错误标志。需要清除它以防止 getline 不断失败。

if (flag) {
   std::cout << "got SIGINT" << std::endl;
   flag = false;
   std::cin.clear();
}
当信号处理程序设置 flag 时,

bool flag = false; 不正确。

正确:

std::sig_atomic_t volatile flag = false;

有关详细信息,请参阅 std::sig_atomic_t