using example I have created two process a master and a slave, to test shared memory IPC. Master creates shared memory and starts writing and after some time slave connects, this is working but onces slave connects its not receiving/getting all the data that master writes to share memory.
master code looks like this:
typedef struct custom_data_s { int min; int max; /* for shared */ pthread_mutex_t ipc_mutex; pthread_cond_t ipc_condvar; } custom_data_t; int main(void) { int fd = -1; custom_data_t *this_custom_data; pthread_mutexattr_t mutex_attr; pthread_condattr_t cond_attr; fd = shm_open("/A_CUSTOM_DATA", O_RDWR | O_CREAT | O_EXCL , (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if(fd == -1) { printf("ERROR fd %d %s\n",fd,strerror(errno)); } if (ftruncate (fd,sizeof(custom_data_t)) == -1) { printf("ERROR trucate fd %d %s\n",fd,strerror(errno)); exit(1); } this_custom_data = (custom_data_t *) mmap(NULL, sizeof(custom_data_t), PROT_READ | PROT_WRITE , MAP_SHARED ,fd ,0); if(this_custom_data ==(custom_data_t *) -1) { printf("ERROR mapping fd %d %s\n",fd,strerror(errno)); exit(1); } close(fd); pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&this_custom_data->ipc_mutex, &mutex_attr); pthread_condattr_init(&cond_attr); pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); pthread_cond_init(&this_custom_data->ipc_condvar, &cond_attr); for (fd=0; fd != 100000; fd++) { pthread_mutex_lock(&this_custom_data->ipc_mutex); this_custom_data->min = fd; this_custom_data->max = fd+5; pthread_cond_signal(&this_custom_data->ipc_condvar); pthread_mutex_unlock(&this_custom_data->ipc_mutex); } /* Clean up and exit should check exit codes of all*/ pthread_mutexattr_destroy(&mutex_attr); pthread_condattr_destroy(&cond_attr); pthread_cond_destroy(&this_custom_data->ipc_condvar); pthread_mutex_destroy(&this_custom_data->ipc_mutex); if(0 != munmap(this_custom_data, sizeof(custom_data_t))) { printf("ERROR unmapping %s\n",strerror(errno)); exit(1); } if (0 != shm_unlink("/A_CUSTOM_DATA")){ printf("ERROR unlinking %s\n",strerror(errno)); exit(1); } return 0; }
For example master starts writing min and max to shared memory from 1 to 10000 after some time slave connects once slave connects it should read all data that is written by master but if in the code once slave connects, it still not reading all data, what I am doing wrong? Should there be another condition variable that slave sets? I am trying to learn shared memory and I think I am doing something wrong or not understanding how mutex and shared memory. In slave I am waiting for condition variable to get set, here is code for slave.
typedef struct custom_data_s { int min; int max; /* for shared */ pthread_mutex_t ipc_mutex; pthread_cond_t ipc_condvar; } custom_data_t; int main(void) { int fd = -1; custom_data_t *this_custom_data_ptr; custom_data_t this_data; int prv_packet = 0; fd = shm_open("/A_CUSTOM_DATA", O_RDWR , (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if(fd == -1) { printf("ERROR fd %d %s\n",fd,strerror(errno)); } if (ftruncate (fd,sizeof(custom_data_t)) == -1) { printf("ERROR trucate fd %d %s\n",fd,strerror(errno)); exit(1); } this_custom_data_ptr = (custom_data_t *) mmap(NULL, sizeof(custom_data_t), PROT_READ | PROT_WRITE , MAP_SHARED ,fd ,0); if(this_custom_data_ptr ==(custom_data_t *) -1) { printf("ERROR mapping fd %d %s\n",fd,strerror(errno)); exit(1); } close(fd); while (1) { pthread_mutex_lock(&this_custom_data_ptr->ipc_mutex); pthread_cond_wait(&this_custom_data_ptr->ipc_condvar, &this_custom_data_ptr->ipc_mutex); memcpy(&this_data, this_custom_data_ptr, sizeof(this_custom_data_ptr)); if (prv_packet == 0){ printf ("got first "); prv_packet = this_data.min; } if ((prv_packet +1) != this_data.min){ printf ("error prv:%d this:%d\n", prv_packet, this_data.min); } pthread_mutex_unlock(&this_custom_data_ptr->ipc_mutex); prv_packet = this_data.min; } return 0; }
What am I doing wrong? How do I synchronize so that once slave is connected it will not loose any data but if its not connected then master will not be blocked also.