Reputation: 5475
I've written the following code to make 2 processes chat using shared memory. But I'm facing some weird problems.
Let's say you send a message from process A, it gets displayed on process B's stdout and you can keep sending messages from process A without any problem. But as soon as you try to send a message from process B, everything stops working. No message is displayed on A. If you now try to send something from A, even that doesn't work. Even worse, if I start a new process, the second process generates a lot of garbage output at first, and then becomes dysfunctional - no further output gets displayed. I don't really understand what's going on.
#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;
}
The reason to split Read and Write in two separate processes is to enable "live" chatting - otherwise scanf will block the execution till something is entered.
And I've also added a simple locking mechanism - I know that the write code here isn't really atomic, but I added it just for, let's say, simulating locking.
Upvotes: 0
Views: 137
Reputation: 3688
I think you need to make lastRead a volatile. It seems to me like one process is caching that value and not getting the update from the other process. Just declare it like this
volatile int lastRead = -1;
Upvotes: 1