共享内存程序表现得很奇怪

时间:2016-03-01 18:16:10

标签: c unix ipc shared-memory

我编写了以下代码,使用共享内存进行2个进程聊天。但我面临一些奇怪的问题。

假设您从进程A发送消息,它会显示在进程B的stdout上,您可以继续从进程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;
}

在两个单独的进程中拆分读写的原因是启用“实时”聊天 - 否则scanf将阻止执行直到输入内容。

我还添加了一个简单的锁定机制 - 我知道这里的编写代码不是真正的原子,但我只是为了模拟锁定而添加它。

1 个答案:

答案 0 :(得分:1)

我认为你需要让lastRead变得不稳定。在我看来,像一个进程缓存该值而不从其他进程获取更新。只是声明它就像这样

volatile int lastRead = -1;