【问题标题】:Program hangs after handling SIGWINCH处理 SIGWINCH 后程序挂起
【发布时间】:2017-07-29 07:35:49
【问题描述】:

只是为了好玩,我正在尝试编写一个库来完成 ncurses 所做的一切,使用 iostreams 并将转义序列直接发送到终端。

我正在尝试处理 SIGWINCH 以在调整终端大小时告诉库。程序正常响应,直到我调整终端大小,然后停止响应输入,甚至是CTRL-C(尽管我没有处理 SIGINT,并且使用 termios 使终端处于“原始”模式)。

这是我从代码中复制的一些代码 sn-ps 以显示我是如何设置信号处理程序的。

void handle_sigwinch(int sig)                                   
{                                                                               
  if(sig == SIGWINCH)    
  {
    // set a flag here
  }
}
void setup_signals()                                            
{       
  struct sigaction new_sig_action;                                            
  new_sig_action.sa_handler = handle_sigwinch;                
  sigemptyset (&new_sig_action.sa_mask);                                      
  new_sig_action.sa_flags = 0;                                                
  sigaction (SIGWINCH, NULL, &old_sig_action_);                               
  if (old_sig_action_.sa_handler != SIG_IGN)                                  
  {                                                                           
    sigaction (SIGWINCH, &new_sig_action, NULL);                              
  }                                                                           
}

int main()
{
  setup_signals();
  int ch;
  // exit if ctrl-c is pressed
  while((ch == cin.get()) != 3)
  {
     if(ch > 0)
       cout << (char)ch;
  }
}

我根据https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html#Sigaction-Function-Example 提供的示例定制了我的代码,用于设置信号处理程序。

在处理 SIGWINCH 后,我是否有什么没做的事情导致我的程序停止工作?

编辑:我省略了使用 cfmakeraw 和 tcsetattr 设置终端的代码,在此之前我发送了一个转义序列,用于将 xterm 置于备用屏幕缓冲区模式。

【问题讨论】:

  • 这段代码是否真的与您正在测试的匹配;具体来说,您是否测试过在 SIGWINCH 处理程序中没有做任何事情,如上面的 sn-ps 所示?
  • 这里的代码看起来不错。请显示您在信号处理程序中拥有的所有实际代码,这可能非常重要。如果您在程序似乎挂起时附加调试器,那么您可能还会在找出问题方面走得很远,这样您就可以看到代码在做什么。
  • @madscientist159 实际上,这就是处理程序所做的一切。它检查信号并且什么也不做。我在那里有一些代码,但是一旦我注意到挂断,我就把它拉出来看看是否是导致问题的原因。它仍然挂起。
  • @nos 我不知道我为什么不这样做;我发帖的时候已经很晚了。我刚刚运行了调试器,我得到了相同的行为,但我可以看到程序实际上并没有“挂起”,它只是没有接收到输入。关于信号处理程序的某些内容必须破坏标准输入(我对此表示怀疑)或cin 流对象。
  • @nos 根据您的建议,我找到了一种更好的方法,可以将我的谷歌搜索表述为“信号处理程序后输入流中断”,并在 Stackoverflow 上找到了正确答案。谢谢!有什么方法可以向您发送代表吗?

标签: c++ terminal signals xterm


【解决方案1】:

感谢nos的评论,我通过调试器发现程序运行正常,但是cin.get()不再接收有效输入。所以我将我的谷歌搜索从“信号处理程序后挂起”更改为“信号处理程序后输入流中断”,并在 StackOverflow 上找到了this 答案,这让我意识到在信号处理程序之后输入流处于错误状态被称为。

我在输入之前放置了一个检查以忽略 -1 的字符值(当我这样做时,我一定一直在考虑 Arduino 库 read 语句,其中 -1 表示没有输入可用) .所以程序基本上忽略了输入流上的错误。 (我编辑了我的问题代码以反映该遗漏)。

我在循环中的读取之前放置了一个cin.clear() 语句,现在程序按预期运行。

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多