c - 编写 10 秒后关闭的 C 程序
问题描述
我想编写一个运行指定秒数的 C 程序,
比如 10 秒然后退出。代码应该设置一个中断,
在指定的时间过去后关闭。
这是我的尝试。但我不确定 SIGALRM 是否是正确的方法。
SIGALRM 可以称为中断吗?
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
void handler()
{
_exit(0);
}
int main()
{
signal(SIGALRM, handler);
alarm(10);
for (;;); /* You can assume that for(;;); is just a dummy code. The main idea is to insert something into code. Whatever code it may be so that it stops after 10 seconds – */
return 0;
}
有什么建议/替代方案/更好的方法来实现这一目标吗?
解决方案
“信号”与“中断”的措辞并不完全清楚。信号可以中断系统调用,所以信号在这个意义上就是中断。但是信号不是硬件中断。当您使用操作系统时,普通程序通常无法直接访问硬件中断。
_exit
如果您的程序需要完成任务或清理某些内容,从信号处理程序调用可能会出现问题。
我建议通过设置一个标志来实现一个优雅的结束。此外,我建议使用sigaction
而不是,因为使用此函数设置signal
的语义和信号处理程序是依赖于实现的。signal
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
static volatile sig_atomic_t timeout = 0;
void handler(int sig)
{
(void) sig;
timeout = 1;
}
int main(void)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
if(sigaction(SIGALRM, act, NULL) < 0)
{
// handle error
}
alarm(10);
while(!timeout /* and maybe other conditions */)
{
// do something, handle error return codes and errno (EINTR)
// check terminate flag as necessary
}
// clean up if necessary
return 0;
}
解释(根据评论中的要求)
static volatile sig_atomic_t timeout = 0;
sig_atomic_t
是一种即使在信号产生异步中断的情况下也能保证原子访问的类型。这意味着对变量的访问不能在两者之间中断,即软件永远不会看到部分修改的值。(见https://en.cppreference.com/w/c/program/sig_atomic_t)
volatile
通知编译器不要优化对变量的访问。这是必要的,因为信号处理程序可能会在主函数运行旨在检查标志的循环时修改值。否则,编译器可能会优化循环条件外的访问,并且只在循环之前执行一次,因为在循环内永远不会修改变量。(见https://en.cppreference.com/w/c/language/volatile)
推荐阅读
- javascript - can't get random # 通过 switch 语句
- java - 如何跨返回整数的不同类访问共享bean实例
- java - 使用 Java 进行自适应卡片渲染和创作
- java - 错误:运行 Spring Boot 应用程序时,由于缺少 EmbeddedServletContainerFactory bean,无法启动 EmbeddedWebApplicationContext
- python - 如何在 tkinter 中修复 scrolledtext 小部件的滚动条的位置?
- video - 即使在转码后,FFMPEG音频/视频在剪切和连接后也不同步
- java - 将功能移动到另一个活动后,无法从 Firestore 中检索文档
- excel - 带有 NamedRange 的 VLookup 函数被引用为字符串
- java - 如何在 Android 上使用 HttpsURLConnection 将 JSON 数据发送到 API?
- c# - 将串行端口设备拆分为两个虚拟 COM,但中间有另一个控制数据流的应用程序