c - “I/O 块状态”和“睡眠”有区别吗?
问题描述
前天我了解到,信号处理程序使进程的“睡眠”失败。
同样,我尝试使用信号处理程序使“读取”失败。
代码如下。
#include <signal.h>
#include <unistd.h>
void signal_handler(int signo)
{
write(1, "\nI've got signal\n", 17);
return;
}
int main()
{
char buf[10];
signal(SIGINT, signal_handler);
read(0, buf, 1);
write(1, buf, 1);
return 0;
}
但是,在执行信号处理程序后,进程又回到 I/O 块状态。
还执行了以下代码以进行重新验证。
#include <signal.h>
#include <unistd.h>
void signal_handler(int signo)
{
write(1, "\nI've got signal\n", 17);
return;
}
int main()
{
char buf[10];
signal(SIGINT, signal_handler);
sleep(100);
write(1, "awake", 5);
return 0;
}
在这种情况下,在收到信号处理程序后,进程不再处于睡眠状态。
有没有办法在收到信号后退出阻塞状态,继续这个过程?(输入失败)
解决方案
根据signal()函数的文档:
signal() 的行为因 UNIX 版本而异,并且在历史上因 Linux 的不同版本而异。避免使用它:使用 sigaction(2) 代替。请参阅下面的可移植性。
...
可移植性
The only portable use of signal() is to set a signal's disposition to SIG_DFL or SIG_IGN. The semantics when using signal() to establish a signal handler vary across systems (and POSIX.1 explicitly permits this variation); do not use it for this purpose.
因此,您应该使用sigaction()而不是 signal()。
如果您在程序中将 signal() 替换为 sigaction() ,它应该可以按预期工作。
推荐阅读
- reactjs - 使用 Framer-motion 悬停在父级时为子级设置动画
- java - 即使我们在 catch 块中处理异常,如何在 spring 中使用 @ControllerAdvice 处理异常
- python - pytesseract - 识别不同背景的文本
- javascript - 在 React Native 应用程序(使用 Expo + Redux)中在哪里初始化 API 密钥(例如:Amplitude)?
- node.js - heroku 不使用纱线缓存模块
- python-3.x - 如何抓取不变的Url的不同页面,这些页面随着Url顶栏上的选项卡而变化?
- golfscript - 这个 GolfScript 代码如何打印 1000 位 pi?
- python - 使用 AWS Lambda 函数将机器学习带入现场生产
- javascript - Node.js 中的单线程究竟是如何工作的?
- ms-word - 在word文档中粘贴MATHML代码时如何解决空格问题?