代码之家  ›  专栏  ›  技术社区  ›  Andrija Petrovic

C中CTRL+C时Raspberry Pi清除退出

  •  2
  • Andrija Petrovic  · 技术社区  · 7 年前

    首先,让我道歉,因为我可以看到类似的问题在过去已经被贴了好几次了。然而,由于我对C非常不熟悉,我需要帮助来确认这一点。

    我试图确保如果我用CTRL+C中断程序,它会留下一个干净的gpio。用python或java很容易做到,但C对我来说是一个很难破解的难题,因为我被引导相信C中最终不存在try-catch。通过谷歌搜索,我找到了我认为可能是解决方案的方法,但尽管我没有经验,但我不确定它是否正确完成。这是我的代码:

    #include <stdio.h>
    #include <wiringPi.h>
    #include <signal.h>
    
    void CleanGPIO() {
        pinMode(1,INPUT);
    }
    int main()
    {
    
        wiringPiSetup();
    
        signal(SIGINT, CleanGPIO);
        pinMode(1, PWM_OUTPUT);
    
        for (int i = 0; i < 1024; ++i) {
            pwmWrite(1, i);
            delay(1);
        }
        for (int i = 1023; i >= 0; --i) {
            pwmWrite(1, i);
            delay(1);
        }
        pinMode(1,INPUT);
        return 0;
    }
    

    我已经对它进行了测试,它按预期工作(在我用CTRL+C中断后,引脚1设置为中),但我担心这是否是安全的方法,以及是否有更好的解决方案可用。

    2 回复  |  直到 7 年前
        1
  •  1
  •   dfogni    7 年前

    从信号处理程序调用任何未指定为信号安全的函数 未定义行为 . 我想没有这样的保证 pinMode .

    正确的方法是设置 volatile int 在主循环中定期检查的标志。

    volatile int terminating = 0;
    
    void terminate(int sign) {
      signal(SIGINT, SIG_DFL);
      terminating = 1;
    }
    
    
    int main() {
    
      for (...) {
        if (terminating) {
           // cleanup
           exit(1);
        }
    
      }
    
    }
    

    呼叫 signal 在处理程序内部,允许使用第二个ctrl+c强制终止程序,以防适当的clenup花费太长时间或由于任何原因而卡住。

        2
  •  0
  •   rghome    7 年前

    您的解决方案几乎是正确的。你也应该打电话 exit 以强制程序终止(假设您要立即终止)。这个 出口 call接受一个参数,该参数是要返回给调用方的退出状态(例如shell)。对于异常终止,该值应为非零。

    因此,它应该是:

    void CleanGPIO() {
        pinMode(1,INPUT);
        exit(1);
    }
    

    如果您不想从处理程序中退出,而是从 main 以一种更受控制的方式,您可以设置一个标志,并检查循环中的标志值。