在 C 中用信号量实现虚拟程序

implementing dummy program with semaphores in C

我正在用 C 语言练习信号量。我写了一个愚蠢的程序,试图从我的 class 笔记中复制一个例子。编译以下代码(gcc -o ex3 ex3.c -lpthread)并执行(./ex3)时,没有任何反应。

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

sem_t S1;
sem_t S2;
sem_t S3;

int main(){

    int fa=4;
    int fb=2;
    int sum=0;

    sem_init(&S1, 0, 1);
    sem_init(&S2, 0, 0);
    sem_init(&S3, 0, 0);

    /* Proceso A*/
    while (fa<4)
    {
        sem_wait(&S1);
        sum = sum + 2;
        sem_post(&S2);
        fa++;
    }

    /* Proceso B*/
    while (fb<2)
    {
        sem_wait(&S2);
        sem_wait(&S2);
        sum = sum + 3;
        sem_post(&S3);
        fb++;
    }

    /* Proceso C*/
    while (1)
    { /* Imprimir */
        sem_wait(&S3);
        printf("%d,", sum);
        sem_post(&S1);
        sem_post(&S1);
        if (fa>4 && fb>2)
            exit(0);
    }

    return 0;
}

我的想法是尝试向进程 A 和 B 添加等待和信号,以便更好地理解这些信号量的作用。但在此之前,我需要查看结果 :D

如有任何帮助,我们将不胜感激。

My idea is to play adding waits and signals to Process A and B in order to understand a bit better what these semaphores do. But before, I need to see the result :D

你的小程序只有一个进程,所以做这个练习的信号量真的很难理解。

的确,它总是因为false表达式而跳过第一个和第二个while循环,然后卡在

sem_wait(&S3);

因为它被初始化为 0 并且永远不会改变。所以它会一直等到这一刻。

我建议初始化

int fa=0;
int fb=0;

这样它将在前两个循环中执行这些操作。此外,为了能够退出最终的 while(1) 循环,我们需要在每次检查 while 表达式后递增 fa 和 fb,而不是在循环结束时递增 fa++/fb++。所以最终的程序看起来像:

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

sem_t S1;
sem_t S2;
sem_t S3;

int main() {

    int fa = 0;
    int fb = 0;
    int sum = 0;

    sem_init(&S1, 0, 4);
    sem_init(&S2, 0, 0);
    sem_init(&S3, 0, 0);

    /* Proceso A*/
    while (fa++ < 4) {
        sem_wait(&S1);
        sum = sum + 2;
        sem_post(&S2);
    }

    /* Proceso B*/
    while (fb++ < 2) {
        sem_wait(&S2);
        sem_wait(&S2);
        sum = sum + 3;
        sem_post(&S3);
    }

    /* Proceso C*/
    while (1) { /* Imprimir */
        sem_wait(&S3);
        printf("%d\n", sum);
        sem_post(&S1);
        sem_post(&S1);
        if (fa > 4 && fb > 2)
            break;
    }

    return 0;
}

此外,我将 exit(0) 调用更改为 break 并将 \n 添加到 printf 而不是逗号,因为它在第一次迭代后退出。

这将打印出 14,然后退出。希望这有助于结果。但是为了更好地理解信号量,我建议从 https://www.cs.mtu.edu/~shene/NSF-3/e-Book/SEMA/basics.html

这样的东西开始