0

我正在尝试通过父进程与其分叉子进程之间的消息队列发送一个 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!"); 
}

这里发生了什么?我以为我的缓冲程序工作正常并且有足够的空间..

4

0 回答 0