You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:40:56