C语言Semaphore实现共享内存交替写入问题求助
共享内存与信号量交替写入问题:死循环无法结束
我编写了一段C语言代码,意图通过信号量(Semaphore)对共享内存进行加锁、解锁操作,向其中写入1字节数据,期望写入的数据能在"message"(值为'a')和"read"(值为'b')之间交替。
可能我对信号量及其锁机制存在误解?我给子进程加了while(1)循环让它持续运行,仅满足if条件时执行写入操作;父进程则执行1000次循环。但程序陷入无法结束的死循环,始终无法完成执行。
代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <time.h> #include <semaphore.h> void latenz_Ausgabe(time_t tv_secStartLatenz, time_t tv_secEndLatenz, long tv_nsecStartLatenz, long tv_nsecEndLatenz) { struct timespec startLatenz = {tv_secStartLatenz, tv_nsecStartLatenz}; struct timespec endLatenz = {tv_secEndLatenz, tv_nsecEndLatenz}; double nanoSekunden = difftime(endLatenz.tv_nsec, startLatenz.tv_nsec); double sekunden = difftime(endLatenz.tv_sec, startLatenz.tv_sec); double differenzZeit = (sekunden + nanoSekunden / ((double) 1e9)) / 1000.0; //Zeit berechnen in Sekunden, sowie auf eine Messung runterrechnen double latenz = (differenzZeit * ((double) 1e3)) / 2; //1e3 für Millisekunden, / 2 Da hin und zurück gemessen printf("Durchschnittliche Latenz: %.6lf milliseconds\n", latenz); } int main() { struct timespec startLatenz, endLatenz; int sem_id; int sem_idtwo; int shm_id; int value; key_t key = ftok("shared_memory", 1); // Create key shared memory key_t keytwo = ftok("semaphore", 1); // Create key semaphore key_t keythree = ftok("semaphoretwo", 1); // Create key semaphore if((shm_id = shmget(key, 16777216, IPC_CREAT | 0666)) == -1){ // -1 indicates error //create shared memory perror("semctl"); exit(1); } else { printf("Shared memory created with id: %d \n", shm_id); } if((sem_id = semget(keytwo, 1, IPC_CREAT | 0666)) == -1){ // -1 indicates error // create semaphore perror("semctl"); exit(1); } else { printf("Semaphore created with id: %d \n", shm_id); } if((sem_idtwo = semget(keythree, 1, IPC_CREAT | 0666)) == -1){ // -1 indicates error // create semaphore perror("semctl"); exit(1); } else { printf("Semaphore created with id: %d \n", shm_id); } struct sembuf sem_lock = {0, -1, 0}; // Struct for semop to lock struct sembuf sem_unlock = {0, 1, 0}; // Struct for semop to unlock char *data = (char *)shmat(shm_id, NULL, 0); // Connect Shared-Memorys to Process pid_t pid; if((semctl(sem_id, 0, SETVAL, 1)) == -1){ // -1 indicates error //initialize the semaphore with value 1 perror("semctl"); exit(1); } else { printf("Semaphore initialized \n"); } if((semctl(sem_idtwo, 0, SETVAL, 1)) == -1){ // -1 indicates error //initialize the semaphore with value 1 perror("semctl"); exit(1); } else { printf("Semaphore initialized \n"); } pid = fork(); if(pid < 0){ printf("Error"); return 1; } //malloc allocates exactly one Byte char *message = (char *) malloc(1); char *read = (char *) malloc(1); message[0] = 'a'; read[0] = 'b'; clock_gettime(CLOCK_MONOTONIC, &startLatenz); if (pid == 0) { // Process 2: while(1){ semop(sem_idtwo, &sem_lock, 1); if (data[0] == message[0]){ memcpy(data, read, 1); } semop(sem_idtwo, &sem_unlock, 1); } } else { // Process 1: for(int i = 0; i < 1000; i++){ //1 if (i > 0){ //because data[0] is never equal to read[0] during first loop semop(sem_id, &sem_lock, 1); //char dummy = data[0]; // Could save current value before overwrite if (data[0] == read[0]){ memcpy(data, message, 1); } semop(sem_id, &sem_unlock, 1); //printf("Values: %c %c \n", dummy, data[0]); //Could print } else{ //because data[0] is never equal to read[0] during first loop semop(sem_id, &sem_lock, 1); //char dummy = data[0]; // Could save current value before overwrite memcpy(data, message, 1); semop(sem_id, &sem_unlock, 1); } } } clock_gettime(CLOCK_MONOTONIC, &endLatenz); latenz_Ausgabe(startLatenz.tv_sec, endLatenz.tv_sec, startLatenz.tv_nsec, endLatenz.tv_nsec); shmdt(data); // Remove shared-memory from process shmctl(shm_id, IPC_RMID, NULL); // Delete shared memory semctl(sem_id, 0, IPC_RMID); // Delete semaphore return 0; }
已尝试的解决方法
- 使用双锁机制
- 调整信号量操作类型
- 更换循环结构(在子/父进程内外调整循环位置)
但以上尝试均未解决问题,程序仍陷入死循环。
内容的提问来源于stack exchange,提问作者Rumapark
相关产品推荐
相关产品推荐

