c - C中信号量的实现

标签 c ipc semaphore

我正在用 C 语言简单地实现一个信号量,虽然我的实现工作正常(作为二进制信号量),但我对它的有效性有疑问。

我的担忧源于我对等待函数的定义:

void Wait(int semid) {
    char *shmPtr;

    shmPtr = shmat(semid, NULL, 0);

    if(shmPtr == (void *) -1){
        printf("Could not attach to semaphore...\n");
        exit(1);
    } 

    //Wait for the value in shared memory to 
    //equal 0, then set it equal to 1,
    //detach and return
    while( (*shmPtr) != 0);

    (*shmPtr) = 1;

    if(shmdt(shmPtr) < 0) {
        printf("Cannot detach from semaphore...");
    }

    return;

}

我的问题在于 while( (*shmPtr) != 0) 环形。假设我们有 2 个正在等待的进程。第三个进程将信号量的值更改为等于 0(忽略这是信号量的二进制实现这一事实)。

我担心的是,如果进程 1 评估 while 循环的条件为假,然后在将信号量值设置为等于 1 之前 CPU 上下文切换到进程 2,则两个进程都将进入临界区。

是否有更好的方法来实现等待功能?我见过很多人使用 pthread_cond_wait,但它使用的互斥体基本上违背了信号量实现的目的。

谢谢

编辑:添加维基百科在 C 中的 TestAndSet 实现以在评论中引用

#define LOCKED 1

int TestAndSet(int* lockPtr) {
    int oldValue;

    oldValue = *lockPtr;
    *lockPtr = LOCKED;
    // -- End of atomic segment --

    return oldValue;
}

最佳答案

正如 Tom 评论的那样,要使信号量正确,您需要原子测试和设置或比较和交换(比较交换)。

但这还不是全部。由于您正在使用共享内存(即通过多个进程),C11 ( Link ) 提供的原子操作是不够的。

既然您无论如何都在调用 Posix 函数,我假设您可以访问 Posix 信号量。

“POSIX 信号量允许进程和线程同步它们的操作。” ( Link )

关于c - C中信号量的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54898512/

相关文章:

java - GWT 与外部独立应用程序交互

Java - 信号量中的优先级

c - 一个系统可以存储多少个信号量?

c - 单车道桥梁问题

c - GLIBC 依赖

按下任意箭头键时更改函数内的变量

c++ - 找到相对于任意原点的两点之间的顺时针角度

c++ - Linux多进程通信多个生产者一个消费者

c - 使用 fprintf 发送方向键

c - 用户输入后出现段错误