C Signal Handler教授实例讲解
C Signal Handler professor example explanation
我的 QNX class 笔记有这个例子,我似乎无法弄清楚我的教授是如何得出这个输出的。任何人都可以向我彻底解释这个吗?
当这个程序运行时,父进程的PID为1234,子进程为5678。
输出
5678: 计数器 = 0
1234: 计数器 = 10
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
/*
* getpid() - returns the current processes pid.
* getppid() - returns the parent processes pid.
*/
int counter = 0;
void signal_handler(int signo)
{
counter++;
}
int main(int argc, char *argv[]) {
int i = 0;
int rv;
struct sigaction sa;
sa.sa_handler = signal_handler;
//queue signals.
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
switch(fork())
{
case 0:
for(i = 0; i < 10; i++)
{
kill(getppid(), SIGUSR1);
}
break;
default:
wait(&rv);
break;
}
printf("%d: counter = %d\n", getpid(), counter);
return 0;
}
fork
使用自己的 counter
副本创建了一个 child 进程。
child 进程调用的 kill
正在向 parent 进程发送 SIGUSR1
,因为它使用 getppid()
获取pid.
parent 进程要么在 wait
中被阻止,要么在 fork
和 wait
之间的某处被阻止。对于 child 发送的每个 SIGUSR1
,parent 将跳转到信号处理程序,将其副本 counter
和 return 递增到它正在做的任何事情.
一般来说,如果信号在等待时被处理,wait
可能会 return 并出现 EINTR
错误。在sa.sa_flags
中设置SA_RESTART
保证系统调用会重启,但是这里假设wait
不会被信号打断(QNX保证吗?)。
child 的 counter
副本不受影响。 wait
导致 parent 阻塞,直到 child 退出。 child 因此打印其值 counter
,即 0
,然后退出,parent 从 wait
中唤醒并打印其值 counter
,也就是 10
.
我的 QNX class 笔记有这个例子,我似乎无法弄清楚我的教授是如何得出这个输出的。任何人都可以向我彻底解释这个吗?
当这个程序运行时,父进程的PID为1234,子进程为5678。
输出 5678: 计数器 = 0 1234: 计数器 = 10
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
/*
* getpid() - returns the current processes pid.
* getppid() - returns the parent processes pid.
*/
int counter = 0;
void signal_handler(int signo)
{
counter++;
}
int main(int argc, char *argv[]) {
int i = 0;
int rv;
struct sigaction sa;
sa.sa_handler = signal_handler;
//queue signals.
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
switch(fork())
{
case 0:
for(i = 0; i < 10; i++)
{
kill(getppid(), SIGUSR1);
}
break;
default:
wait(&rv);
break;
}
printf("%d: counter = %d\n", getpid(), counter);
return 0;
}
fork
使用自己的 counter
副本创建了一个 child 进程。
child 进程调用的 kill
正在向 parent 进程发送 SIGUSR1
,因为它使用 getppid()
获取pid.
parent 进程要么在 wait
中被阻止,要么在 fork
和 wait
之间的某处被阻止。对于 child 发送的每个 SIGUSR1
,parent 将跳转到信号处理程序,将其副本 counter
和 return 递增到它正在做的任何事情.
一般来说,如果信号在等待时被处理,wait
可能会 return 并出现 EINTR
错误。在sa.sa_flags
中设置SA_RESTART
保证系统调用会重启,但是这里假设wait
不会被信号打断(QNX保证吗?)。
child 的 counter
副本不受影响。 wait
导致 parent 阻塞,直到 child 退出。 child 因此打印其值 counter
,即 0
,然后退出,parent 从 wait
中唤醒并打印其值 counter
,也就是 10
.