【问题标题】:IPC mechanism using message queues in C在 C 中使用消息队列的 IPC 机制
【发布时间】:2014-04-05 09:41:59
【问题描述】:

我正在尝试使用 C 中的消息队列为电话对话实现 IPC 机制。我创建了两个 .c 文件,一个用于呼叫者,一个用于接收者。在每个 .c 文件中,我创建了两个线程,一个用于发送消息,另一个用于接收消息。每个线程创建它的消息队列。来自调用者的发送消息线程和来自接收者的接收消息线程共享相同的队列并且彼此相同。

正在创建消息队列,但是每当我输入要发送的消息时,它都会失败。 msgsnd(-,-,-,-) 总是返回 -1。

caller.c文件如下:

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

struct msgbuf
{
  long mtype;
  char mtext[50];
}SEND_BUFFER,RECEIVE_BUFFER;

int send_msgQ_id, receive_msgQ_id;
key_t send_key,receive_key;

void * send_message(void * a)
{
send_key = ftok("Caller.c", 'B');
if(send_key==-1)
{
    printf("\n caller send key error");
    exit(1);
}
send_msgQ_id = msgget(send_key, 0666 | IPC_CREAT);
if(send_msgQ_id==-1)
{
    printf("\n caller send msgget error");
    exit(1);
}

printf("\n Enter lines of text, ^D to quit:\n");

    while(fgets(SEND_BUFFER.mtext, sizeof(SEND_BUFFER.mtext), stdin) != NULL)
    {
        SEND_BUFFER.mtype = 0;

        int len = strlen(SEND_BUFFER.mtext);
        if (SEND_BUFFER.mtext[len-1] == '\n')
            SEND_BUFFER.mtext[len-1] = '\0';
        printf("\n Attemping to send %s\n", SEND_BUFFER.mtext);
        if(msgsnd(send_msgQ_id, &SEND_BUFFER, len+1, 0)==-1)
            printf("\n msg sendign error\n");
    }
int i =0;
while(i<9999)
    i++;
msgctl(send_msgQ_id, IPC_RMID, NULL);
return;
}

void * receive_message(void * a)
{
receive_key = ftok("Receiver.c", 'B');
if(receive_key==-1)
{
    printf("\n caller receive key error");
    exit(1);
}
receive_msgQ_id = msgget(receive_key, 0777 | IPC_CREAT);
 if(receive_msgQ_id==-1)
 {
     printf("\n caller receive msgget error");
     exit(1);
 }

printf("\n Ready to receive ");
while(1)
{
   if( msgrcv(receive_msgQ_id, &RECEIVE_BUFFER, sizeof(RECEIVE_BUFFER.mtext), 0, 0)!=-1)
    printf("Received : %s\n", RECEIVE_BUFFER.mtext);
}
return;
}

void initialize()
{

pthread_t send_thread,receive_thread;
pthread_create(&send_thread,NULL,send_message,NULL);
pthread_create(&receive_thread,NULL,receive_message,NULL);
pthread_join(send_thread,NULL);
pthread_join(receive_thread,NULL);
return;
}

int main()
{
printf("\n\n *** Caller Program ***\n");
initialize();
return 0;
}

receiver.c文件如下(与caller.c文件类似):

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

struct msgbuf
{
long mtype;
char mtext[50];
}SEND_BUFFER,RECEIVE_BUFFER;

int send_msgQ_id, receive_msgQ_id;
key_t send_key,receive_key;

void * send_message(void * a)
{
send_key = ftok("Receiver.c", 'B');
if(send_key==-1)
{
    printf("\n receiver send key error");
    exit(1);
}
send_msgQ_id = msgget(send_key, 0777);
if(send_msgQ_id==-1)
{
    printf("\n receiver msgget error ");
    exit(1);
}
printf("\n Enter lines of text, ^D to quit:\n");

    SEND_BUFFER.mtype = 0;
    while(fgets(SEND_BUFFER.mtext, sizeof(SEND_BUFFER.mtext), stdin) != NULL)
    {
        int len = strlen(SEND_BUFFER.mtext);
        if (SEND_BUFFER.mtext[len-1] == '\n')
            SEND_BUFFER.mtext[len-1] = '\0';
        msgsnd(send_msgQ_id, &SEND_BUFFER, len+1, 0);
    }
    int i =0;
    while(i<9999)
        i++;
msgctl(send_msgQ_id, IPC_RMID, NULL);
return;
}

void * receive_message(void * a)
{
receive_key = ftok("Caller.c", 'B');
if(receive_key==-1)
{
    printf("\n receiver receiver key error");
    exit(1);
}
receive_msgQ_id = msgget(receive_key, 0666);
if(receive_msgQ_id==-1)
{
    printf("\n msgget error");
    exit(1);
}

while(1)
{
    if(msgrcv(receive_msgQ_id, &RECEIVE_BUFFER, sizeof(RECEIVE_BUFFER.mtext), 0, 0)==-1)
        printf("\n msg receiving error");
    else
        printf("Received : %s\n", RECEIVE_BUFFER.mtext);
}
return;
}

void initialize()
{
pthread_t send_thread,receive_thread;
pthread_create(&receive_thread,NULL,receive_message,NULL);
pthread_create(&send_thread,NULL,send_message,NULL);
pthread_join(send_thread,NULL);
pthread_join(receive_thread,NULL);
return;
}

int main()
{
printf("\n\n *** Receiver Program ***\n");
initialize();
return 0;
}

我需要呼叫者和发送者都可以随意接收和发送消息。

【问题讨论】:

  • 失败怎么办?具体错误是什么?你添加了operating-system 标签,但没有告诉我们你正在处理什么操作系统。删除该标签并告诉我们。
  • 我在 UNIX 操作系统上运行它。每次都显示“消息发送失败”。 msgsnd(-,-,-,-) 总是返回 -1。
  • 好的,失败时errno 设置为什么?调试是一个有条不紊的过程,您需要阅读手册页。

标签: c multithreading unix message-queue


【解决方案1】:

您收到的errno 表示您将无效参数传递给msgsnd。根据man page for msgsnd

[EINVAL] msqid 的值不是有效的消息队列标识符,或者 mtype 的值小于 1;或者 msgsz 的值小于 0 或大于系统施加的限制。 块引用

我的猜测是msqid 是有问题的参数。在调试器中检查值或将其打印出来。

编辑:迈克·威尔金斯发现了它。他的评论:

mtype 可能是问题所在(不是 msqid)。 mtype 需要 > 0。代码 在 OP 中专门将其设置为 0

【讨论】:

  • 我认为您引用的文字显示了答案。 mtype 可能是问题所在(不是 msqid)。 mtype需要>0。OP中的代码专门设置为0。
  • @MarkWilkins 不错。添加到答案中。
猜你喜欢
  • 2013-01-05
  • 2012-09-19
  • 2021-03-12
  • 2014-05-04
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多