簡體   English   中英

使用 sigprocmask 和 sigsuspend 在兩個進程之間反彈信號

[英]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 parentparent has the ball and will throw it to the child的評論是不真實的。 您必須在等待之前決定要發送一個進程,例如父進程。
  • 您必須為ball安裝一個信號處理程序(可以像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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM