如何使用信号在进程之间进行同步?
How to make synchronization between processes using signals?
objective 是 parent 进程应该生成一个 child,parent 打印 1 到 100 之间的偶数,child打印奇数。这种机制应该使用信号来实现(显然数字应该按顺序排列,例如 parent:0、child:1、parent:2...)我编写了以下代码:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
for(int i=0; i<=100; i++){
if (i % 2 != 0){
printf("I am the child: %d\n", i);
}
}
} else {
kill(pid, SIGSTOP);
for(int i=0; i<=100; i++){
if(i % 2 == 0){
printf("I am the parent: %d\n", i);
kill(pid, SIGCONT);
}
}
wait(NULL);
}
return 0;
}
但是输出不是按照应有的顺序,parent 首先打印他的所有数字,child 紧随其后。我想知道 SIGSTOP 和 SIGCONT 是不是适合使用的信号,但没有其他合理的解决方案。
任何建议都会有所帮助。谢谢。
阻止信号并仅在收到该信号时恢复。关于使用哪个信号,您可以使用任何可以被阻止的信号(除 SIGKILL
、SIGSTOP
之外的任何信号)。我使用 SIGRTMIN
因为它是用于应用程序定义的目的。
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
/* Block SIGRTMIN */
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGRTMIN);
if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0)
exit(1);
int signo;
/* Spawn a new child */
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
sigwait(&sigmask, &signo); // This is to make parent start first.
for(int i=1; i<=100; i=i+2){
printf("I am the child: %d\n", i);
kill(getppid(), SIGRTMIN); // Resume parent
sigwait(&sigmask, &signo); // Wait for parent
}
} else {
for(int i=0; i<=100; i=i+2){
printf("I am the parent: %d\n", i);
kill(pid, SIGRTMIN); // Resume child
if (i == 100) // Parent stucks at sigwait after printing 100.
break;
sigwait(&sigmask, &signo); // Wait for child
}
wait(NULL);
}
return 0;
}
我们在父级中阻止了 SIGRTMIN 但它如何在子级中被阻止?
根据 signal(7)
手册页。
A child created via fork(2) inherits a copy of its parent's
signal mask; the signal mask is preserved across execve(2).
objective 是 parent 进程应该生成一个 child,parent 打印 1 到 100 之间的偶数,child打印奇数。这种机制应该使用信号来实现(显然数字应该按顺序排列,例如 parent:0、child:1、parent:2...)我编写了以下代码:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
for(int i=0; i<=100; i++){
if (i % 2 != 0){
printf("I am the child: %d\n", i);
}
}
} else {
kill(pid, SIGSTOP);
for(int i=0; i<=100; i++){
if(i % 2 == 0){
printf("I am the parent: %d\n", i);
kill(pid, SIGCONT);
}
}
wait(NULL);
}
return 0;
}
但是输出不是按照应有的顺序,parent 首先打印他的所有数字,child 紧随其后。我想知道 SIGSTOP 和 SIGCONT 是不是适合使用的信号,但没有其他合理的解决方案。
任何建议都会有所帮助。谢谢。
阻止信号并仅在收到该信号时恢复。关于使用哪个信号,您可以使用任何可以被阻止的信号(除 SIGKILL
、SIGSTOP
之外的任何信号)。我使用 SIGRTMIN
因为它是用于应用程序定义的目的。
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main(){
/* Block SIGRTMIN */
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGRTMIN);
if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0)
exit(1);
int signo;
/* Spawn a new child */
pid_t pid;
pid = fork();
if (pid == -1){
return 1;
}
if (pid == 0){
sigwait(&sigmask, &signo); // This is to make parent start first.
for(int i=1; i<=100; i=i+2){
printf("I am the child: %d\n", i);
kill(getppid(), SIGRTMIN); // Resume parent
sigwait(&sigmask, &signo); // Wait for parent
}
} else {
for(int i=0; i<=100; i=i+2){
printf("I am the parent: %d\n", i);
kill(pid, SIGRTMIN); // Resume child
if (i == 100) // Parent stucks at sigwait after printing 100.
break;
sigwait(&sigmask, &signo); // Wait for child
}
wait(NULL);
}
return 0;
}
我们在父级中阻止了 SIGRTMIN 但它如何在子级中被阻止?
根据 signal(7)
手册页。
A child created via fork(2) inherits a copy of its parent's signal mask; the signal mask is preserved across execve(2).