親プロセスとそのフォークされた子の間のメッセージ キューを介して 1KB の文字列を送信しようとしています。残念ながら、 、 などへの呼び出しmsgsnd
がmsgrcv
突然すべて -1 を返し、EINVAL
エラーが発生します。
このエラー (msgsnd
たとえば の場合) がmsqid
無効な場合、メッセージ タイプ引数が <1 に設定されている場合、またはmsgsz
が範囲外の場合に発生することがわかりました。しかし、テストすると、私が知る限りmsgget
、完全に有効な ID 番号が返され、タイプは適切に設定されています。バッファー範囲に問題があるに違いありませんが、正しく設定したと思います。コードには、説明するコメントを追加しました (必死に追加された #includes のすべてについて申し訳ありません)。
#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cstring>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <sstream>
#define PERMS (S_IRUSR | S_IWUSR)
#define NUMBYTES 1024 //number of chars (bytes) to be sent
using namespace std;
//Special structure for messages
typedef struct {
long mtype;
char mtext[NUMBYTES];
} mymsg_t;
int main(){
//Construct a generic test message of the specified size
char message[NUMBYTES];
for(int i = 0; i < NUMBYTES; i++)
message[i] = 'a';
//Create the message queue (accessed by both parent
//and child processes)
int msqid;
int len;
if(msqid = msgget(IPC_PRIVATE, PERMS) == -1)
perror("Failed to create new message queue!\n");
if(fork() == 0){ //Child process...does the sending
mymsg_t* mbuf;
len = sizeof(mymsg_t) + strlen(message); //doesn't work with " + sizeof(message)" either
void* space;
if((space = malloc(len)) == NULL) //this works fine; no error output
perror("Failed to allocate buffer for message queue.\n");
mbuf = (mymsg_t*)space;
strcpy(mbuf->mtext, message);
mbuf->mtype = 1; //a default
//Some error checks I tried...
//cout<<"msqid is " << msqid << endl;
//cout << "mbuf ptr size is " << sizeof(mbuf) << ". And this non-ptr: "<<sizeof(*mbuf)<<". And
//len: "<<len<<endl;
if(msgsnd(msqid, mbuf, len+1, 0) == -1)
perror("Failed to send message.\n"); //this error occurs every time!
free(mbuf);
}
else{ //Parent process...does the receiving
usleep(10000); //Let the message come
mymsg_t mymsg; //buffer to hold message
int size;
if((size = msgrcv(msqid, &mymsg, len+1, 0, 0)) == -1) //error every time
perror("Failed to read message queue.\n");
//checking that it made it
//cout << "Hopefully printing it now? : " << endl;
//if(write(STDOUT_FILENO, mymsg.mtext, size) == -1)
// perror("Failed to write to standard output!\n");
}
ostringstream oss;
oss << "ipcrm -q " << msqid;
string command = oss.str();
if(system(command.c_str()) != 0) //also errors every time, but not main focus here
perror("Failed to clean up message queue!");
}
ここで何が起こっているのですか?バッファー手順が正常に機能し、十分なスペースがあると思いました..