【发布时间】:2017-04-28 09:58:48
【问题描述】:
最近我正在学习 Linux 上的进程通信。我写了一个 C 程序来做以下事情:
- 进程A设置消息队列(如邮箱)
- 进程 B 依次向队列发送三个消息“111”、“222”、“333”。
- 进程 C 从队列中按“333”、“111”、“222”的顺序读取消息。
- 进程 D 删除队列。
我首先在 Ubuntu 16.04 上编写了这个程序,它运行良好,正如我想象的那样:
但是,当我编译相同的代码并尝试在 macOS(Sierra 10.12.3) 上运行时,结果与 Ubuntu 上的不同:
无论我如何更改代码(例如,在进程 A 中休眠几秒钟),队列总是在第三条消息发送之前被删除。
这是我的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <errno.h>
#define MAX_TEXT 1024
struct mymsg123
{
long int priority;
char text[MAX_TEXT];
};
int main()
{
int msgid = -1; //message id
struct mymsg123 data; //message to send
//set up message queue(mailbox) in Process A
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed in Process A with error: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("Mailbox created in Process A\n");
pid_t pid = fork(); //to create Process B
if (pid < 0) {fprintf(stderr, "Fork failed in Process A"); exit(EXIT_FAILURE); }
//child Process B
else if (pid == 0)
{
const char msg1[] = "111";
//set the first message
data.priority = 2;
strcpy(data.text, msg1);
//send the first message
if (msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed in Process B when sending msg1\n");
exit(EXIT_FAILURE);
}
printf("Sent msg %s, priority %ld to mailbox\n", data.text, data.priority);
const char msg2[] = "222";
//set the second message
data.priority = 3;
strcpy(data.text, msg2);
//send the second message
if (msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed in Porcess B when sending msg2\n");
exit(EXIT_FAILURE);
}
printf("Sent msg %s, priority %ld to mailbox\n", data.text, data.priority);
const char msg3[] = "333";
//set the third message
data.priority = 1;
strcpy(data.text, msg3);
//send the third message
if (msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed in Process B when sending msg3\n");
exit(EXIT_FAILURE);
}
printf("Sent msg %s, priority %ld to mailbox\n", data.text, data.priority);
}
//parent Process A
else
{
pid_t pid = fork(); //to create Process C
if (pid < 0) {fprintf(stderr, "Fork failed in Process A"); exit(EXIT_FAILURE); }
//child process C
else if (pid == 0)
{
//receiving priority 1 message
long int priority = 1;
if(msgrcv(msgid, (void*)&data, BUFSIZ, priority, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error in Process C when receiving priority 1 msg: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("Received priority 1 message in Process C from mailbox: %s\n", data.text);
//receiving priority 2 message
priority = 2;
if(msgrcv(msgid, (void*)&data, BUFSIZ, priority, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error in Prcess C when receiving priority 2 msg: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("Received priority 2 message in Process C from mailbox: %s\n", data.text);
//receiving priority 3 message
priority = 3;
if(msgrcv(msgid, (void*)&data, BUFSIZ, priority, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error in Process C when receiving priority 3 msg: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("Received priority 3 message in Process C from mailbox: %s\n", data.text);
}
//parent Process A
else
{
pid_t pid = fork(); //to create Process D
if (pid < 0) {fprintf(stderr, "Fork failed in Process A"); exit(EXIT_FAILURE); }
//child process D
else if (pid == 0)
{
//sleep(10);
if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed in Process D\n");
exit(EXIT_FAILURE);
}
printf("Mailbox deleted in Process D\n");
}
//parent Process A
else
;
}
}
//sleep(10);
exit(EXIT_SUCCESS);
}
高级感谢!
【问题讨论】:
标签: linux message-queue ubuntu-16.04 macos-sierra