2

こんにちは、メッセージキューを介して一連のバイトを送信するプログラムを書いています...

#include <sys/msg.h>
#include <stddef.h>

key_t key;
int msqid;
struct pirate_msgbuf pmb = {2, { "L'Olonais", 'S', 80, 10, 12035 } };

key = ftok("/home/beej/somefile", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);

/* stick him on the queue */
msgsnd(msqid, &pmb, sizeof(struct pirate_msgbuf) - sizeof(long), 0);

上記の例は、私のものに似た beejs Web サイトの単純なプログラムです。

しかし、私がやっていることは、そのような構造体でメッセージを送信することです...

struct msg_queue{

    long message_type;
    char * buffer;

}

msg_queue を送信する前に、null 文字などを含むあらゆる種類の情報を含む代替バッファーを作成しました。今、私がこのようなことをすると...

struct msg_queue my_queue;
my_queue.message_type = 1;
my_queue.buffer = "My message";
msgsnd(mysqid, &pmb, sizeof(struct msg_queue) - sizeof(long), 0);

ポインターを受け取り、その文字列に格納されている値を読み取ることに問題はありません。しかし、私が似たようなことをするなら...

struct msg_queue my_queue;
my_queue.message_type = 1;
my_queue.buffer = sum_buffer_with_lots_of_weird_values; // of type char *
msgsnd(mysqid, &pmb, sizeof(struct msg_queue) - sizeof(long), 0);

キューを介して他のプロセスに渡すポインターは、格納されている値ではなくガベージを読み取ります。任意の配列を static char * として作成しようとしましたが、それも役に立ちません。キューを介してバッファを適切に渡すにはどうすればよいですか? ありがとう。

4

3 に答える 3

5

別のプロセスにポインターを送信するべきではありません。別のプロセスのアドレス空間では意味がありません (または非常に異なるものを指しています)。

メッセージ キューは、可変長文字列のような無制限のデータには適していません。ポインターを、最大の文字列を保持するのに十分な大きさの固定長の char 配列に変更し、キューを書き込む前に文字列を配列にコピーします。または、ドメイン ソケットなどの別のタイプの IPC を使用します。

于 2012-10-31T01:06:23.553 に答える
2

Message Queue is used for inter-process communication. When you malloc some memory in one process, it only exist in that process memory space not accessible by other process.

when you send that pointer over, you are sending a address space which is not accessible. It may even result in segmentation fault.

One way is to limit your buffer size, if applicable.

struct msg_queue{

long message_type;
char buffer[MAX_LEN];

}

Another way is to send it 2 times. The first msgsnd, sends the size of buffer to expect. The next send, you send the char array over, using the size of the first send. :)

On receiving end, you first get the size, then receive the buffer.

Other way is to use pipes or socket.

于 2012-10-31T08:50:06.110 に答える
1

「msgsend()」は、バッファ内のバイトのみを読み取ります。

これらのバイトの 1 つがたまたま (別の場所にある文字列またはオブジェクトへの) ポインターである場合、何を推測しますか? 受信側はバイナリ ポインターを取得するだけです。指しているデータではありません。

必要なことは、メッセージの内容全体をバッファーにパックしてから、その線形バッファーを送信することです。

于 2012-10-31T01:06:38.240 に答える