1

我刚刚在 linux 上学习 IPC,并想出了三个简单的程序。一种是创建(并在功能中管理)消息队列。第二个应该只是将消息发送到第一个创建的队列。第三个程序是从队列中接收数据。

所有程序都从同一个根目录继承,并根据源代码和二进制文件插入到单独的目录中。

所以让我们只专注于创建和发送部分,这也将帮助我修复第三个程序。

添加队列 main.c:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define FAILED -1


int main(int argc, char *argv[]) {
  // message data
  key_t key;
  int msgqid;

  if ((key = ftok("../src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if ((msgqid = msgget(key, 0666 | IPC_CREAT)) == FAILED) { /* create an message queue with owner & group & others permission set to rw- */
    perror("msgget");
    exit(1);
  }

  printf("Message Queue %i with key %i, been created [press return to delete]", msgqid, key);
  getchar();

  if (msgctl(msgqid, IPC_RMID, NULL) == FAILED) {
    perror("msgctl");
    exit(1);
  }
  printf("I'm outta here! \n");

  return 0;
}

发送 main.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <stddef.h>
#include <string.h>

#include "../../lib/shared_msgbuf.h" /* mbuf, MSGSZ */

#define FAILED -1


int main(void) {
  char s[MSGSZ];

  printf("Enter a message: ");

  if (fgets(s, sizeof s, stdin) == NULL)
    perror("fgets");
  else 
    strcpy(mbuf.mtext, s);

  printf("Connecting to the queue... \n", s);

  // Setup
  key_t key;
  int msgqid;

  if ((key = ftok("../../adqueue/src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if (msgqid = msgget(key, 0666) == FAILED) {
    perror("msget");
    exit(1);
  }

  printf("\n*CONNECTION ESTABLISHED* \n");
  printf("queue id: %i \n", msgqid);
  printf("queue key: %d \n", key);
  printf("message: %s \n", s);

  printf("Sending the message... \n");
  if (msgsnd(msgqid, &mbuf, MSGSZ, 0) == FAILED) {
    perror("msgsnd");
    exit(0);
  }

  return 0;
}

所以问题是我Invalid argument在尝试发送消息时收到错误号。查看数据,我不明白为什么 id 不匹配,因为与队列的连接似乎有效......

示例数据:

./cadqueue 
Message Queue 327680 with key 1510081535, been created [press return to delete]

./send 
Enter a message: test
Connecting to the queue... 

*CONNECTION ESTABLISHED* 
queue id: 0 
queue key: 1510081535 
message: test

Sending the message... 
msgsnd: Invalid argument
4

2 回答 2

2

您的错误来自这一行:

if (msgqid = msgget(key, 0666) == FAILED) {

它应该是

if ((msgqid = msgget(key, 0666)) == FAILED) {

在第一种情况下,由于运算符优先级,比较 ( ==) 在分配 ( =) 之前完成。

在第二种情况下,括号告诉编译器必须首先做什么。

于 2017-11-15T14:12:00.363 回答
1

这些是所需的头文件msgsnd()

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

为了可移植性,发布的代码缺少其中两个头文件包含语句

===========

这个说法:

if (msgqid = msgget(key, 0666) == FAILED) {

缺少IPC_CREAT应该是0666参数一部分的

===========

mbuf两个字段,mtype字段,必须为正,> 0 和mtext字段。

发布的代码正在设置该mtext字段,但未能设置该mtype字段。

==============

这个说法:

printf("Connecting to the queue... \n", s);

有一个输入参数的问题,但它们在“格式字符串”中没有格式说明符

=============

对于同一消息队列的每次访问,该key值必须相同。

所以调用ftok()必须都具有相同的参数,否则它们将通过调用生成不同/唯一的消息队列msgget()

=============

注意:消息队列不会因为程序退出而“消失”。因此,应该调用控制程序(或最后一条消息的最后一个用户)msgctl()来删除消息队列

于 2017-11-17T02:32:33.663 回答