2017-02-01 14 views
1

メッセージキューを理解しようとしています。私が見た例では、msgのstrunctは、最初のもの(型)以外の属性が1つだけあり、それはlongでなければなりません。だから、struct msg{long mtype; char text[100]};のようなものになります。メッセージキューはどのように動作するはずですか?

新しいint属性を追加しようとしましたが、xという文字と数字の両方を受け取ったかどうかを確認しました。

メッセージキューはどのように動作するはずですか? structに何個も属性を設定できますか?

そして、また、それは私がのsizeof構造体は、常に、各属性のsizeofの合計と同じではないことを知っているのでsizeof(send) - sizeof(send.x)に設定された長さのパラメータを持つmsgrcvmsgsnd関数を呼び出すokですか? ありがとうございます。

int main(){ 

    struct msg{ 
     long mtype; 
     char text[100]; 
     int x; 
    }; 

    int key = ftok(".", 10); 
    int qid = msgget(key, 0666|IPC_CREAT); 

    int pid = fork(); 

    if(pid == 0){ 
     struct msg send; 
     send.mtype = 1; 
     strcpy(send.text, "hello"); 
     send.x = 99; 
     if(msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.x), 0)<0){ 
      printf("Error child: "); 
     } 
    } 
    else{ 
     struct msg recieve; 
     if(msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(recieve.x), 1, 0)<0){ 
      perror("Error parent: "); 
     }; 
     printf("text: %s\nnumber: %d", recieve.text, recieve.x); 
    } 

    return 0; 
} 

答えて

1

のchar []は単なるプレースホルダで、あなたが必要な長いMTYPEフィールド後の構造で好きなことができます。 msgsnd()呼び出しのサイズにはmtypeは含まれません。

あなたはほぼ正しいと思います。ここで

が作業バージョンです:

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

int main(void){ 

    struct msg { 
     long mtype; 
     char text[100]; 
     int x; 
    }; 

    size_t sz = sizeof(struct msg) - sizeof(long); <=== /* SIZE */ 
    int key = ftok(".", 10); 
    int qid = msgget(key, 0666|IPC_CREAT); 

    int pid = fork(); 

    if (pid == 0){ 
     struct msg send; 
     send.mtype = 1; 
     strcpy(send.text, "hello"); 
     send.x = 99; 
     if (msgsnd(qid, (void*)&send, sz, 0)<0){ 
      perror("Error child: "); 
     } 
    } else { 
     struct msg recieve; 
     if(msgrcv(qid, (void*)&recieve, sz, 1, 0)<0){ 
      perror("Error parent: "); 
     }; 
     printf("text: %s\nnumber: %d\n", recieve.text, recieve.x); 
    } 

    return 0; 
} 
+0

お返事ありがとうございますが、バージョンと私の違いはわかりません。 size_t sz = sizeof(struct msg) - sizeof(long)は、sizeof(recieve) - sizeof(recieve.x)と同じです。何か不足していますか? –

+0

'int'と' long'が同じサイズの場合、数値的には「等価」です。 –

+0

意味的には、 'mtype'のサイズを減算するのは正しいです。送信したいフィールドを減算することは正しくありません( 'x'など)。 –

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

msgpパラメータはconst void*として宣言されているので、あなたが好きなデータタイプを使用することができます。ちょうどlongchar[]structでなければならないということは何もありません。つまり、sizeof(send)を実行するだけです。送信している余分な構造体メンバを調整する必要はありません。実際には、構造体全体が処理されないため、問題が発生します。重要なのは、msgrcv()が前のmsgsnd()と同じ構造体を使用していることだけです。 this exampleを参照してください。でman pageから

+0

'charは[]'単なるプレースホルダで、あなたが必要な '長いmtype'フィールド後の構造で好きなことができます。 'msgsnd()'呼び出しのサイズは 'mtype'を含んでいません。 –

+0

@JohnHascall 'mtype'は必須ですか? –

+0

はい、構造体はメッセージ型の 'long'で始まる必要があります。あなたは 'mtype'と呼ぶ必要はありませんが、それは通常の習慣です。 –

4

:msgp引数は 以下の一般的な形式の 発信者定義構造体へのポインタである

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

msgpは以下のように定義されます

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

太字ここでの主なポイントは、構造体であることが、発信者が定義しある

私のものです。したがって、入力構造体(msgsndによって送信され、出力構造体(msgrcvによって受信される)が同じである限り、mtypeに続くデータは、(サイズを正しく指定する限り)任意のものにすることができます。あなたのケースでは、あなたが本当に唯一必要があります。

msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.mtype), 0) 

msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(send.mtype), 1, 0) 
関連する問題