2017-11-15 9 views
0

共有ファイルの値を変更するには、信号p1 - > p2 - > p3 - > p1 ...を送信する必要があります。しかし、p3 - > p1は機能しません(p1はシグナルを捕まえません)。私はそれぞれの移行の間に時間差を作るために睡眠を入れたが、何が間違っているのかはわからない。Cの3つのプロセス間で同期信号を送信するには

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <signal.h> 
#include <setjmp.h> 
void sig_usr (int signo) 
{ 
     printf("%d\n",getpid()); 
//  longjmp(jumpbuffer,1); 
} 

int main(int argc, char **argv) 
{ 
     signal(SIGUSR1, sig_usr); 
     jmp_buf jumpbuffer; 
     pid_t next,ppid,granmaduh; 
     granmaduh = getpid(); 
     if ((next = fork()) <0) 
     { 
         fprintf(stderr, "fork() error"); 
         exit(1); 
     } 
     else if (next == 0 ) 
     { 

       next = fork(); 
       if (next >0) 
       { 

         sleep(6); 
       } 
       else 
       { 
         next = granmaduh;  
         sleep(10); 
       } 
     } 
     sleep(2); 
     printf("%d\n",next); 
     //setjmp(jumpbuffer); 


     kill(next, SIGUSR1); 
     exit(1); 
} 
+0

P2 P1の子、P3はP2の子が、P1とP3の間には接続されている...それはこの実装 –

+0

であなたの問題だ何私は次のP1のPIDとしてP3年代を添加していない。(次回= granmaduh)ので、 p3が信号を送信しようとすると、それはp1に送られませんか? – r3dr4bb1t

+0

Deja-vu。 3つの名前付きセマフォを使用します。 –

答えて

0
#include <signal.h> 
#include <stdio.h> 
#include <sys/wait.h> 
#include <errno.h> 

static void signal_handler(int); 
int i, pid1, pid2,pid3, status; 

int main(int argc, char *argv[], char *env[]) 
{ 
    int exit_status; 

    if(signal(SIGUSR1, signal_handler) == SIG_ERR ) 
    { 
     printf("Pærent: Unable to create handler for SIGUSR1\n"); 
    } 

    // if(signal(SIGUSR2, signal_handler) == SIG_ERR ) 
    // { 
    //  printf("Pærent: Unable to create handler for SIGUSR2\n"); 
    // } 

    printf("Parent pid = %d\n", pid1=getpid()); 

    if((pid2 = fork()) == 0) 
    { 
     printf("Child pid = %d\n", getpid()); 
     //printf("Child: %d sending parent SIGUSR1\n", getpid()); //kill(pid1, SIGUSR1); 

     if((pid3 = fork()) == 0) 
     { 
     printf("GranChild pid = %d\n", getpid()); 
     printf("Child: %d sending parent SIGUSR1\n", getpid()); kill(pid2, SIGUSR1); 
     } 
     for(;;); /* loop forever */ 

    } 
    else 
    { 
     /* 
     * This waits for ANY child to die. It doesn't matter if the child 
     * dies normally or from a signal. The satus information is then 
     * stored in the status integer. 
     * 
     * If you want to wait on a particular process use waitpid(): 
     *  waitpid(childPID, &status, 0); 
     * is the common usage. 
     * 
     * Solaris acts weirdly when a signal is given to the parent process. 
     * Therefore we place the wait() inside a while loop so that wait() 
     * will not return before the child has died. 
     */ 
     /* while((wait(&status) == -1) && (errno == EINTR)) {} */ 

     wait(&status); 

     /* 
     * The information in status is *NOT* the return code!! To make use 
     * of the information we must macros to extract the needed 
     * information. 
     */ 

     /* WIFEXITED() determines if the process exited normally (returned a 
     * number). This can be done through a return or exit() 
     */ 

     if(WIFEXITED(status)) 
     { 
      /* 
      * Now we know the process exited properly so we can get the 
      * return value 
      * 
      * Note that WEXITSTATUS only retuns the lower 8 bits! That means 
      * that if we ever expect a negative number then we have to count 
      * the 8th bit as a sign bit. 
      */ 

      exit_status = WEXITSTATUS(status); 

      /* 
      * Since we expect negative numbers... 
      * 
      * If the exit_status is greater than 2^7 (128), thæn the eigth bit 
      * is a 1, so we subtract 2^8 (256) from it to make it look like 
      * a negative number. 
      */ 
      if(exit_status > 128) 
      { 
       exit_status -= 256; 
      } 

      printf("Child return - %d\n", WEXITSTATUS(status)); 
     } 
     else 
     { 
      /* Well it didn't exit properly. Was it a signal? */ 
      if(WIFSIGNALED(status)) 
      { 
       /* 
       * Yes. A signal killed the child process. Now we can extract 
       * the signal information from status 
       */ 

       printf("Child died on signal - %d\n", WTERMSIG(status)); 
      } 
     } 

     /* 
     * There are two other macros most UNIXes use. They are: 
     * WIFSTOPPED() and WSTOPSIG(). See the man pages on the dells for 
     * more information. 
     * 
     * To wait on a particular pid - see waitpid() 
     */ 
    } 

    return 0; 
} 

static void signal_handler(int signo) 
{ 

    /* signo contains the signal number that was received */ 
    switch(signo) 
    { 
     /* Signal is a SIGUSR1 */ 
     case SIGUSR1: 
      printf("Process %d: received SIGUSR1 \n", getpid()); 
      if(pid1==getpid()) /* it is the parent */ 
      { 
        printf("Process %d is passing SIGUSR1 to %d...\n", getpid(),pid2); 
        kill(pid2, SIGUSR1); 
      } 
      else if(pid2==getpid()) /* it is the child */ 
      { 
        printf("Process %d is passing SIGUSR2 to itself...\n", getpid()); 
        kill(getpid(), SIGUSR2); 
      } 
      else 
      { 
       printf("Process %d is passing SIGUSR2 to itself...\n", getpid()); 
        kill(pid3, SIGUSR2); 
      } 

      break; 

     /* It's a SIGUSR2 */ 
     case SIGUSR2: 
      printf("Process %d: received SIGUSR2 \n", getpid()); 
      if(pid1==getpid()) 
      { 
        printf("Process %d is passing SIGUSR2 to %d...\n", getpid(),pid2); 
        kill(pid2, SIGUSR2); 
      } 
      else if(pid2==getpid())/* it is the child */ 
      { 
        printf("Process %d is passing SIGUSR2 to %d...\n", getpid(),pid3); 
        kill(pid3, SIGINT); 
      } 
      else /* it is the child */ 
      { 
        printf("Process %d is passing SIGUSR2 to %d...\n", getpid()); 
        kill(getpid(), SIGINT); 
      } 
      break; 

     default: 
       break; 
    } 

    return; 
} 
+0

インフラストラクチャ3のプロセス間通信です。ここから続けることを願っています –

関連する問題