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

如何用Semaphore同步C语言父子进程使输出仅为a=20

Hey there! Let's break down why your code is printing both outputs, and fix it to only show a=20 while keeping that if check in the child process.

The Core Issues

  1. Semaphores aren't shared between parent and child
    When you use sem_init(&sem1, 0, 1), the second parameter 0 tells the system this semaphore is only shared between threads within the same process. After fork(), the child gets a copy of the parent's memory—so sem1 and sem2 are completely separate in each process. That means your sem_wait/sem_post calls don't actually synchronize anything; both processes can run their code without blocking each other.

  2. The variable a is process-private
    Global variables aren't shared across processes after fork(). The child gets its own copy of a, and the parent gets its own. So when the child sets a=10, it's only modifying its own version, and the parent's a=20 is a separate value. That's why both if conditions trigger and print.

Fixing the Code

To make this work, we need two things:

  • Shared semaphores (so parent and child can actually sync)
  • Shared memory for a (so both processes modify the same variable)

We'll use named semaphores (via sem_open) for inter-process sync, and mmap to create shared memory for a. We'll also adjust the semaphore logic to ensure the parent modifies a to 20 before the child checks its value—so the child's if (a == 10) condition fails and doesn't print.

Here's the corrected code:

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>

// Names for our named semaphores
#define SEM_CHILD_DONE "/sem_child_done"
#define SEM_PARENT_DONE "/sem_parent_done"

int main() {
    // Create shared memory for variable 'a'
    int fd = shm_open("/shared_a", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int));
    int *a = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    *a = 0; // Initialize shared 'a' to 0

    // Initialize named semaphores
    sem_unlink(SEM_CHILD_DONE); // Clean up if semaphores exist from prior runs
    sem_unlink(SEM_PARENT_DONE);
    sem_t *sem_child_done = sem_open(SEM_CHILD_DONE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0);
    sem_t *sem_parent_done = sem_open(SEM_PARENT_DONE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0);

    pid_t pid = fork();

    if (pid == 0) {
        // Child process: set a=10, then wait for parent to update it to 20
        *a = 10;
        sem_post(sem_child_done); // Notify parent we've set a=10
        
        sem_wait(sem_parent_done); // Wait for parent to modify a to 20
        if (*a == 10) { // This condition will now be false
            printf("a = %d\n", *a);
        }

        // Cleanup child resources
        sem_close(sem_child_done);
        sem_close(sem_parent_done);
        munmap(a, sizeof(int));
        close(fd);
    } else {
        // Parent process: wait for child to set a=10, then update to 20
        sem_wait(sem_child_done); // Wait for child to set a=10
        
        *a = 20;
        if (*a == 20) { // This condition is true, so we print
            printf("a = %d\n", *a);
        }
        sem_post(sem_parent_done); // Notify child we've updated a

        // Wait for child to finish, then cleanup parent resources
        wait(NULL);
        sem_close(sem_child_done);
        sem_close(sem_parent_done);
        sem_unlink(SEM_CHILD_DONE);
        sem_unlink(SEM_PARENT_DONE);
        munmap(a, sizeof(int));
        close(fd);
        shm_unlink("/shared_a");
    }

    return 0;
}

How This Works

  1. Shared a: We use shm_open and mmap to create a shared memory region, so both parent and child access the exact same int value.
  2. Semaphore Sync:
    • The child sets a=10, then signals the parent via sem_child_done.
    • The parent waits for that signal, then sets a=20, prints it, and signals the child via sem_parent_done.
    • The child waits for the parent's signal before checking a—by this time, a is 20, so the if (a ==10) condition fails and nothing is printed from the child.
  3. Cleanup: We unlink semaphores and shared memory to avoid leaving resources hanging after the program exits.

Compilation Note

Don't forget to link against the real-time library when compiling:

gcc your_program.c -o your_program -lrt

内容的提问来源于stack exchange,提问作者katerina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:15:51