2015-09-20 23 views
3

該過程創建n個子節點(n從stdin讀取),並且每個節點必須每隔2秒向父節點發送一條消息,然後將收到的每條消息發送給所有兒童。我正在使用2個消息隊列:其中一個是所有的孩子都發送消息給父母,另一個是父母發送消息並且每個孩子都讀取消息。每個成功發送或接收的孩子都會打印它的pid和來自msg隊列的數據(數據只是一個隨機數)。 但是該程序顯示錯誤「msgsnd:無效的參數。」 我已經做了一些調試,以檢查傳遞的參數是否爲空或無效,但不是這樣。 Noe我有點卡住,並不確定如何繼續。任何幫助,將不勝感激。父和子之間的消息隊列在msgsnd中導致無效參數

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <stdio.h> 
#include <string.h> 
#include <signal.h> 
#include <time.h> 

typedef struct msgbuf { 
    long mtype; 
    int  num; 
} message_buf; 

long n; 
void sigalrm(int signo){ 
     alarm(5); 
     n=n+2; 
     printf("%ld seconds elapsed\n",n); 
     } 
int main(int argc,char *argv[]){ 
    int id1,id2; 
    int msgflg = IPC_CREAT | 0666; 
    key_t key1,key2; 
    key1 = ftok ("test2.c", 'A'); 
    key2 = ftok ("test2.c", 'B'); 
    message_buf sbuf,rbuf; 
    size_t buf_length=sizeof(int); 

    time_t t; 


     pid_t pid; 
     int i,j,k,n; 
     n=atoi(argv[1]); 

     if ((id1 = msgget(key1, msgflg)) < 0) { 
       perror("msgget"); 
      } 
     else 
      printf("Queue 1 created\n"); 

     if ((id2 = msgget(key2, msgflg)) < 0) { 
       perror("msgget"); 
      } 
     else 
      printf("Queue 2 created\n");   

     for(i=0;i<n;i++) { 
     pid = fork(); 
     if(pid==0) { 
     setpgid(getpid(),getppid()); 
     signal(SIGALRM, sigalrm); 
     alarm(2); 
     while(1)  { 
       srand((unsigned)time(&t)); 
       sbuf.mtype = i; 
       sbuf.num=rand()%50; 

       if (msgsnd(id1, &sbuf, buf_length,0) < 0) { 
         perror("msgsnd"); 
       } 
       else { 
       printf("msg sending successful\n"); 
       printf("%ld\t%d\n",(long)getpid(),sbuf.num); 
      } 
     pause(); 
// paused so that now parent can send the messages before children receive it 

      for(j=0;j<n;j++) { 

      if (msgrcv(id2, &rbuf, buf_length, j, 0) < 0) { 
       perror("msgrcv"); 
       } 
      else { 
       printf("msg receiving successful\n"); 
       printf("%ld\t%d\n",(long)getpid(),sbuf.num); 
      } 
     } 

    } 

} 

else if(pid>0) { 


while(1) { 
sleep(3); 
//sleeping so that children can first send the message 
      if (msgrcv(id1, &rbuf, buf_length,0, IPC_NOWAIT) < 0) { 
       perror("msgrcv"); 
       } 
      else { 
       printf("msg receiving successful\n"); 

      sbuf.num=rbuf.num; 
      sbuf.mtype=rbuf.mtype; 
for(k=0;k<n;k++) { 
      if (msgsnd(id2, &sbuf, buf_length, IPC_NOWAIT) < 0) { 
       perror("msgsnd parent\n"); 
       //exit(1); 

      } 
     } 
    } 
    } 

} 
} 
} 

輸出:

Queue 1 created 
Queue 2 created 
msgsnd: Invalid argument 
2 seconds elapsed 
msgrcv: No message of desired type 
msgrcv: No message of desired type 
4 seconds elapsed 
msgrcv: Interrupted system call 
msgrcv: No message of desired type 
6 seconds elapsed 
msgrcv: Interrupted system call 
msgrcv: No message of desired type 
msgrcv: No message of desired type 
8 seconds elapsed 
msgrcv: Interrupted system call 

(used ctrl+c here). 
+0

您可以在哪個平臺上使用哪種C實現編譯此代碼? – alk

+0

與你的問題完全無關,但不需要重複執行'srand(time(...))'。在程序開始時只做一次就足夠了。 – WhiteViking

+0

@WhiteViking thnx指出。 –

回答

4

msgsnd man page

...的MTYPE領域必須有一個嚴格整數值。 ...

...

EINVAL

將對msqid無效值,或傳力MTYPE值,或無效msgsz 值(小於0或大於系統值MSGMAX更大)。

您不能發送消息mtype設置爲零。

+0

是的。這解決了msgsnd問題。 Thnx很多。 –

相關問題