![](/img/trans.png)
[英]Sigsuspend equivalent to atomic series of sigprocmask, pause, sigprocmask?
[英]Using sigprocmask and sigsuspend to bounce signal between two processes
我正在學習操作系統基礎知識,並得到了我想要實現的這個想法:我想創建一個父進程和一個子進程。 這兩個過程將在彼此之間反彈 N 次信號。 我的想法是孩子和父母互相打球。 我想使用 SIGUSR1 作為“球”在它們之間發送。 我使用了 sigsuspend() 和 sigprocmask() 以便每個進程在將信號發回之前等待來自另一個進程的信號。 但是,我不確定我是否正確實現了 sigsuspend 和 sigprocmask:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
//playing ball with one parent and child process for N times
int N= atoi (argv[1]);
pid_t child_pid;
pid_t vfork(void);
sigset_t newmask, waitmask;
child_pid = vfork();
sigemptyset(&waitmask);
sigemptyset(&newmask);
sigaddset(&waitmask, SIG_BLOCK);
sigaddset(&newmask, SIGUSR1);
if(child_pid < 0){
return 1;
}
while(N !=0){
if(child_pid == 0){
//the child has the ball and will throw it to the parent
sigprocmask(SIG_BLOCK, &newmask, &waitmask);
sigsuspend(&waitmask);
printf("Hey parent throw the ball\n");
sigprocmask(SIG_UNBLOCK, &newmask, NULL);
kill(getppid(), SIGUSR1);
printf("Hey parent catch the ball\n");
N--;
}
else{
//parent has the ball and will throw it to the child
sigprocmask(SIG_BLOCK, &newmask, &waitmask);//parent waits for the child to throw ball
sigsuspend(&waitmask);
printf("Hey child throw the ball\n");
sigprocmask(SIG_UNBLOCK, &newmask, NULL);
kill(child_pid, SIGUSR1);
printf("Hey kid catch the ball\n");
N--;
}
}
}
附加庫用於其他功能系統調用,我希望以后能夠正確運行這個系統調用。 我使用 vfork() 而不是 fork() 因為我讀到父進程將保持掛起狀態,直到子進程完成其執行。 更新代碼:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
//ps aux | awk {'print $8'}|grep -c Z
void handler(int signum){} //CHANGE HERE
int main(int argc, char** argv){
//playing ball with one parent and child process for N times
int N= atoi (argv[1]);
pid_t child_pid;
sigset_t newmask, waitmask;
sigprocmask(SIG_BLOCK, &newmask, &waitmask);
child_pid = fork();
sigemptyset(&waitmask);
sigemptyset(&newmask);
sigaddset(&waitmask, SIG_BLOCK);
sigaddset(&newmask, SIGUSR1);
if(child_pid < 0){
return 1;
}
while (N--) //NEW CHANGE HERE
if (child_pid == 0)
{
printf("Hey, parent, throw the ball!\n");
sigsuspend(&waitmask);
// the child has the ball and will throw it to the parent
printf("Hey, parent, catch the ball!\n");
kill(getppid(), SIGUSR1);
}
else
{
// parent has the ball and will throw it to the child
signal(SIGUSR1, handler); // CHANGE HERE
printf("Hey, kid, catch the ball!\n");
kill(child_pid, SIGUSR1);
printf("Hey, child, throw the ball!\n");
sigsuspend(&waitmask);
}
}
使用 N = 4 測試時的 Output 圖像./catch 4
我使用了 sigsuspend() 和 sigprocmask() 以便每個進程在將信號發回之前等待來自另一個進程的信號。
the child has the ball and will throw it to the parent
和parent has the ball and will throw it to the child
的評論是不真實的。 您必須在等待之前決定要發送一個進程,例如父進程。void handler(int signum) {}
一樣簡單),否則它會殺死想要捕獲它的可憐進程: signal(SIGUSR1, handler);
sigprocmask(SIG_BLOCK, &newmask, &waitmask)
必須在fork()
之前調用,否則信號可以在進程等待它之前傳遞,並且以后的等待將永遠持續。 出於同樣的原因,不能調用sigprocmask(SIG_UNBLOCK, &newmask, NULL)
。 所以,循環可以變成: while (N--) if (child_pid == 0) { printf("Hey, parent, throw the ball;\n"); sigsuspend(&waitmask), // the child has the ball and will throw it to the parent printf("Hey, parent; catch the ball,\n"); kill(getppid(), SIGUSR1), } else { // parent has the ball and will throw it to the child printf("Hey; kid, catch the ball;\n"), kill(child_pid, SIGUSR1); printf("Hey; child, throw the ball!\n"); sigsuspend(&waitmask); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.