Raspberry Pi 在 C 中按 CTRL+C 清除退出
Raspberry Pi clean exit on CTRL+C in C
首先,让我道歉,因为我看到类似的问题在过去已经发布了很多次。但是,由于我对C非常陌生,我需要帮助确认这一点。
如果我用 CTRL+C 中断我的程序,我试图确保它留下一个干净的 gpio。在 python 或 java 中很容易完成,但事实证明 C 对我来说更难破解,因为我被引导相信 C 中不存在 try-catch-finally。谷歌搜索,我发现我认为可能是解决方案,但我没有经验,我不确定它是否正确完成。这是我的代码:
#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 被设置为 IN),但我担心这是否是安全的方法,如果有有更好的解决方案。
您的解决方案几乎是正确的。您还应该调用 exit
以强制程序终止(假设您想立即终止)。 exit
调用带有一个参数,该参数是调用者 return 的退出状态(例如 shell)。对于异常终止,这应该是非零的。
所以,应该是:
void CleanGPIO() {
pinMode(1,INPUT);
exit(1);
}
如果您不想从处理程序中退出,而是想以更可控的方式从 main
中退出,您可以改为设置标志并检查循环内的标志值。
从信号处理程序调用任何未指定为信号安全的函数是未定义的行为。我想关于 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 强制终止程序,以防适当的清理花费太长时间或因任何原因卡住。
首先,让我道歉,因为我看到类似的问题在过去已经发布了很多次。但是,由于我对C非常陌生,我需要帮助确认这一点。
如果我用 CTRL+C 中断我的程序,我试图确保它留下一个干净的 gpio。在 python 或 java 中很容易完成,但事实证明 C 对我来说更难破解,因为我被引导相信 C 中不存在 try-catch-finally。谷歌搜索,我发现我认为可能是解决方案,但我没有经验,我不确定它是否正确完成。这是我的代码:
#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 被设置为 IN),但我担心这是否是安全的方法,如果有有更好的解决方案。
您的解决方案几乎是正确的。您还应该调用 exit
以强制程序终止(假设您想立即终止)。 exit
调用带有一个参数,该参数是调用者 return 的退出状态(例如 shell)。对于异常终止,这应该是非零的。
所以,应该是:
void CleanGPIO() {
pinMode(1,INPUT);
exit(1);
}
如果您不想从处理程序中退出,而是想以更可控的方式从 main
中退出,您可以改为设置标志并检查循环内的标志值。
从信号处理程序调用任何未指定为信号安全的函数是未定义的行为。我想关于 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 强制终止程序,以防适当的清理花费太长时间或因任何原因卡住。