英文:
Why is this application being closed?
问题
处理信号是否会以任何方式关闭应用程序?我的目标是在时间用尽时执行某些操作,但在循环中被卡住,直到用户输入q或找到EOF,但由于某种原因,一旦收到信号,应用程序似乎根本不执行循环,只是打印printf("returning from main!!\n");并退出应用程序。我错过了什么?我该如何修复这个问题?
以下是完整的代码:
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ucontext.h>
#include <unistd.h>
void thread_signal_handler(int signal)
{
// 线程的时间片用尽,切换到另一个线程
// ...
printf("时间用尽了!!!\n");
}
int main()
{
// 为线程的时间片设置信号处理程序
struct sigaction sa;
sa.sa_handler = thread_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
// 为线程的时间片设置定时器
struct itimerval timer;
timer.it_value.tv_sec = 5;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, NULL);
while (1)
{
int ch = getchar();
if (ch == 'q' || ch == EOF)
break;
}
printf("从main返回!!\n");
return 0;
}
Hope this helps!
英文:
Does handling signals make the application close in anyway? my goal is to do some action when time run out but get stuck in the loop, until the user enter q or EOF is found but for some reason as soon the singal is received, the application seem to not execute the loop at all just print printf("returning from main!!\n"); and exit from the application. What am I misisng? how do i fix that?
here's the full code:
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ucontext.h>
#include <unistd.h>
void thread_signal_handler(int signal)
{
// Thread's time slice has run out, switch to another thread
// ...
printf("time run out!!!\n");
}
int main()
{
// Set up the signal handler for the thread's time slice
struct sigaction sa;
sa.sa_handler = thread_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
// Set up the timer for the thread's time slice
struct itimerval timer;
timer.it_value.tv_sec = 5;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, NULL);
while (1)
{
int ch = getchar();
if(ch == 'q' || ch == EOF) break;
}
printf("returning from main!!\n");
return 0;
}
答案1
得分: 2
信号处理程序在getchar
等待用户输入时被触发。
信号处理程序返回后,getchar
返回EOF,errno
设置为EINTR
,表明调用被中断。这导致循环退出。
英文:
The signal handler is getting fired while getchar
is waiting for user input.
After the signal handler returns, getchar
returns EOF and errno
is set to EINTR
, indicating that the call was interrupted. This causes your loop to exit.
答案2
得分: 2
如果发生读取错误,流的错误指示器将被设置,getchar()
将返回EOF,并设置errno以指示错误。
getchar()
函数在需要读取数据且出现以下情况时会失败:
- EINTR
读取操作由于接收到信号而被终止,且没有数据被传输。
信号处理程序完成后,执行将返回到信号中断它的点。然后,getchar()
返回EOF,因为它被信号中断,并将errno
设置为EINTR
,这将导致while
循环退出。
话虽如此,您的代码会触发未定义行为,因为printf()
是异步信号不安全的,也就是说,不能安全地在信号处理程序内调用它(无论是在C标准中还是在POSIX标准中)。
尽管如此,POSIX标准定义了write()
系统调用是异步信号安全的,可以用来替代printf()
:
write(STDOUT_FILENO, "time run out!!!\n", 17);
英文:
> If a read error occurs, the error
> indicator for the stream shall be set, getchar() shall return EOF,
> and shall set errno to indicate the error.
The getchar()
function shall fail if data needs to be read and:
> EINTR
>
> The read operation was terminated due to the receipt of a
> signal, and no data was transferred.
After the signal handler completes, execution returns to the point right where the signal interrupted it. getchar()
then returns EOF
because it was interrupted by a signal, and sets errno
to EINTR
, which causes the while
loop to exit.
That being said, your code simply invokes undefined behaviour because printf()
is async-signal-unsafe, i.e. it can't be called safely inside a signal handler. (Neither in the C standard, nor the POSIX standard).
Though, the POSIX standard does define the write()
syscall to be async-signal-safe that can be used instead of printf()
:
write (STDOUT_FILENO, "time run out!!!\n", 17);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论