非阻塞的send、阻塞的receive类型的消息通信机制实现生产者消费者问题代码实现
时间: 2024-02-23 07:00:29 浏览: 62
下面是在 C 语言中使用非阻塞的 send 和阻塞的 receive 类型的消息通信机制实现生产者消费者问题的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define MSG_SIZE 1024
struct msgbuf {
long mtype;
char mtext[MSG_SIZE];
};
int main() {
int msgid, len;
struct msgbuf buf;
key_t key;
pid_t pid;
// 创建消息队列
if ((key = ftok(".", 'a')) == -1) {
perror("ftok");
exit(1);
}
if ((msgid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("msgget");
exit(1);
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
// 子进程为消费者
while (1) {
memset(&buf, 0, sizeof(struct msgbuf));
// 阻塞接收消息
if (msgrcv(msgid, &buf, MSG_SIZE, 1, 0) == -1) {
perror("msgrcv");
exit(1);
}
printf("Consumer received: %s\n", buf.mtext);
if (strcmp(buf.mtext, "end") == 0) {
break;
}
}
exit(0);
} else {
// 父进程为生产者
while (1) {
memset(&buf, 0, sizeof(struct msgbuf));
printf("Input message: ");
fgets(buf.mtext, MSG_SIZE, stdin);
len = strlen(buf.mtext);
if (buf.mtext[len-1] == '\n') {
buf.mtext[len-1] = '\0';
}
buf.mtype = 1;
// 非阻塞发送消息
if (msgsnd(msgid, &buf, len, IPC_NOWAIT) == -1) {
perror("msgsnd");
}
if (strcmp(buf.mtext, "end") == 0) {
break;
}
}
// 等待子进程结束
wait(NULL);
// 删除消息队列
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(1);
}
exit(0);
}
return 0;
}
```
该程序中,通过使用 IPC 消息队列实现了生产者消费者问题。父进程为生产者,子进程为消费者,两者之间通过消息队列进行通信。
父进程从标准输入读取消息,并通过非阻塞的方式发送到消息队列中,而子进程则通过阻塞的方式接收消息队列中的消息。当父进程输入 "end" 时,程序结束并退出。
需要注意的是,在父进程中发送消息时使用了非阻塞的方式,这是为了防止消息队列满了之后阻塞父进程,从而导致程序死锁。如果消息队列已满,父进程会直接输出错误信息并继续等待输入。
阅读全文