I'm trying to create a program in C for Unix. Given an array I should pass every item of the array from parent process to its child through shared memory and using a semaphore. This is what I've got.
const key_t sem_key = (key_t)0x12345611; const key_t shm_key = (key_t)0x12339611; int sem_wait(int semafor_id) { struct sembuf sb; sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = SEM_UNDO; return semop(semafor_id, &sb, 1); } int sem_signal(int semafor_id) { struct sembuf sb; sb.sem_num = 0; sb.sem_op = 1; sb.sem_flg = SEM_UNDO; return semop(semafor_id, &sb, 1); } int main(int argc, char *argv[]) { int status; char str[3]; str[0] = 'z'; str[1] = 'x'; str[2] = 'y'; // Create shared memory int memory_id = shmget(shm_key, 1, 0600 | IPC_CREAT | IPC_EXCL); if (memory_id < 0) { printf("Shared memory creating failed\n"); return 1; } // Create semafor int semafor_id = semget(sem_key, 10, 0600 | IPC_CREAT | IPC_EXCL); if (semafor_id < 0) { printf("SEMAFOR creating failed\n"); return 1; } semctl(semafor_id, 0, SETVAL, 1); // init semafor pid_t pid = fork(); if (pid < 0) printf("FORK FAILED\n"); else if (pid > 0) { printf("PARENT\n"); void *address = shmat(memory_id, NULL, 0); if (address == NULL) { printf("Failed to attach memory\n"); return 1; } if (sem_wait(semafor_id) < 0) // sem_wait() decrements (locks) the semaphore pointed to by sem. { printf("Failed wait parent\n"); return 1; } for (int i = 0; i < 3; i++) { void *address = shmat(memory_id, NULL, 0); if (address == NULL) { printf("Failed to attach memory\n"); return 1; } printf("writer started.\n"); char *data = (char *) address; *data = str[i]; printf("writer ended.\n"); } if (shmdt(address) != 0) printf("Failed to detach shared memory\n"); if (sem_signal(semafor_id) < 0) printf("Failed signal parent\n"); else printf("Parent leave generating number\n"); // wait for child wait(&status); printf("Destroy semafor\n"); semctl(semafor_id, 0, IPC_RMID, 0); printf("Destroy shared memory\n"); shmctl(memory_id, IPC_RMID, 0); return 0; } // close parent case else { printf("CHILD\n"); if (sem_wait(semafor_id) < 0) printf("FAILED wait child\n"); else { void *address = shmat(memory_id, NULL, 0); if (address == NULL) { printf("Failed to atach memory in child\n"); return 1; } char *data = (char *) address; printf("Child read data %c\n", *data); if (shmdt(address) != 0) printf("Failed to detach shared memory in child\n"); } } if (sem_signal(semafor_id) < 0) printf("Failed signal child\n"); else printf("Leave data reading\n"); return 0; } The current output is this:
writer started writer ended writer started writer ended writer started writer ended child read data y destroy semafor destroy shared memory As you can see the parent write in the shared memory 3 times and then the child get the access of the shared memory printing the data of the shared memory. The output I'd like to have is this:
writer started writer ended child read data z writer started writer ended child read data x writer started writer ended child read data y destroy semafor destroy shared memory