2017-05-29 98 views
0

所以程序就是這樣工作的。有一個生產者和4個消費者。生產者生成6個隨機數並通過消息隊列將它們發送給4個消費者。每個消費者接收它們,並且在終止之前立即 ,應該通過另一個隊列發送mayproduce = 0的一條消息; mayproduce是一個整數。消息隊列不接受0作爲參數

有問題的功能是:

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 

我使用的功能像這樣送mayproduce

msgsnd(qid,&mayproduce,sizeof(int),0) 

當我編譯它說: 「無效參數」。

如果我改變mayproduce爲其他號碼,mayproduce = 2,程序工作正常。

有誰知道它不接受0作爲參數的原因嗎?

的代碼示例:

mayproduce=2; // if I put 0 here it doesn't work 
if(msgsnd(msq2,&mayproduce,tamanho,0)<0) { 
    perror("\nConsumidor:Erro ao enviar a mensagem: "); 
    exit(1); 
} 
+1

顯示完整的錯誤消息。完整的代碼或至少是完整的代碼片段。 –

+0

'mayproduce == 0'不像「將'mayproduce'設置爲另一個數字」。這是將'mayproduce'設置爲0或1的比較。由於缺乏MCVE而投票結束。 –

+0

是的@WeatherVane這是我的錯誤。我的意思是mayproduce = 0 – Ackerman

回答

1

msgsnd()文檔狀態:

The msgp argument is a pointer to a caller-defined 
    structure of the following general form: 

     struct msgbuf { 
      long mtype;  /* message type, must be > 0 */ 
      char mtext[1]; /* message data */ 
     }; 

的幫助頁中,你需要閱讀非常非常多了很多信息小心。

所以你不是真的應該發送一個指針到一個int。您應該創建自己的結構,其中1.成員的類型爲long,並用作消息類型鑑別符,接收方可以查看它以確定它接收的消息類型。

您傳遞給msgsend()的大小是您發送的所有內容在mtype成員之後的大小。

當執行msgsnd(qid,&mayproduce,sizeof(int),0)會發生以下情況:

  • mayproduce INT被解釋爲在一個struct msgbufmtype構件,作爲文檔說,它不能爲0
  • 的的sizeof(int)的說你除了long msgtype之外還會有一個int。但您的&mayproduce指針只是指向一個int,因此您可能還會從堆棧中抓取垃圾值。

你應該這樣做:

struct MyMsg { 
    long mtype; 
    int mayproduce; 
}; 

struct MyMsg msg; 
msg.mtype = 1; //or whatever you want > 0 
msg.mayproduce = ....; //whatever you want to send. 
size_t msgsize = sizeof(struct MyMsg) - sizeof(long); 

msgsnd(msq2,&msg,msgsize,0); 
+0

是不是計算'msgsize'容易被填充?如果(比如說)long是8字節而int是4,那麼sizeof(struct MyMsg)可能是16,並且結束填充。這並不能保證,但這對於一個對齊的64位體系結構來說是典型的。因此它會計算出'msgsize = sizeof(struct MyMsg) - offsetof(struct MyMsg,mayproduce);'as 8.因此會發送陷阱表達式。如果接收者僅查看前4個字節,但不是「msgsize = sizeof(int)」正確答案,那麼這不一定有害? – Persixty

+0

@Persixty爲什麼會發送陷阱表達式?我們分配了一個struct MyMsg,並且告訴msgsnd()發送從'mayproduce'開始的所有8個字節到最後,包括填充(如果有的話)。我懷疑大小的計算不是很正確,但是如果在'mtype'和'mayproduce'之間有填充,會在接收端讀入同一個結構時產生問題。這個計算可能只是'sizeof(struct MyMsg) - sizeof(long)' – nos

+0

也許我濫用術語陷阱表達式......我的意思是(在64位對齊的體系結構上)將導致8字節發送時只有4個是有意義的。將另外4個字節複製到結構中將會很好。 如果(比如說)成員類型對齊> long,並且在成員之前存在填充,它甚至無法幫助,因爲我看不到'msgsend'除了複製'sizeof(long) + msgsz'左右。 安全的(但不合法的)代碼將與'sizeof(struct MyMsg)-sizeof(long)'一起傳遞,並且傳遞所有的填充,我們確信'mtype'在'struct'的開始處 – Persixty