【发布时间】:2016-06-14 07:27:09
【问题描述】:
我编写了以下代码,以使 2 个进程使用共享内存进行聊天。但我面临一些奇怪的问题。
假设您从进程 A 发送一条消息,它会显示在进程 B 的标准输出上,您可以继续从进程 A 发送消息而没有任何问题。但是,一旦您尝试从进程 B 发送消息,一切都会停止工作。 A 上没有显示任何消息。如果您现在尝试从 A 发送内容,即使这样也不起作用。更糟糕的是,如果我启动一个新进程,第二个进程首先会产生大量垃圾输出,然后变得功能失调 - 不再显示输出。我真的不明白发生了什么。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
struct message {
int senderid;
char msg[100];
};
struct message_q {
int write_ptr;
int writing;
struct message msgbuffer[100];
} *pmsgq;
key_t key;
int shmid;
int lastRead = -1;
void handleRead() {
while(1) {
while(lastRead+1 != pmsgq->write_ptr) {
// don't display our own messages
if(pmsgq->msgbuffer[1+lastRead].senderid != getppid())
printf("Remote: %s\n",pmsgq->msgbuffer[++lastRead].msg);
}
}
}
void handleWrite() {
char msg[100];
while(1) {
scanf("%s", msg);
while(pmsgq->writing)
;
pmsgq->writing = 1;
strcpy(pmsgq->msgbuffer[pmsgq->write_ptr].msg, msg);
pmsgq->msgbuffer[pmsgq->write_ptr].senderid = getpid();
pmsgq->write_ptr++;
pmsgq->writing = 0;
}
}
int main() {
key = ftok("shared_mem_chat.c",'b');
shmid = shmget(key, sizeof(struct message_q), IPC_CREAT | 0666);
pmsgq = (struct message_q*) shmat(shmid, NULL, 0);
pmsgq->write_ptr = 0;
pmsgq->writing = 0;
if(fork() == 0) {
handleRead();
}
else {
handleWrite();
}
return 0;
}
将 Read 和 Write 拆分为两个独立进程的原因是为了启用“实时”聊天 - 否则 scanf 将阻止执行,直到输入某些内容。
我还添加了一个简单的锁定机制 - 我知道这里的编写代码并不是真正的原子,但我添加它只是为了模拟锁定。
【问题讨论】:
-
1) 添加代码以检查来自
shmget()、shmat()的返回值,以确保操作成功。 2) 添加代码以检查来自fork()的返回值何时失败。 3) 完成共享内存后,将指针传递给shmdt()。 4)主进程在退出前必须调用wait()或waitpid()。子进程不能调用shmdt()
标签: c unix ipc shared-memory