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

时间:2016-12-17 19:42:09

标签: c semaphore

我在C语言中练习信号量。我写了一个愚蠢的程序,试图从我的班级笔记中复制一个例子。编译下面的代码(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

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

  

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

您的小程序中只有一个进程,因此很难理解进行此练习的信号量。

实际上,它总是跳过第一个和第二个while循环,因为它表示错误,然后它被卡在了

sem_wait(&S3);

因为它被初始化为0并且永远不会改变。所以它会在这一点上永远等待。

我建议初始化

int fa=0;
int fb=0;

这样它就可以完成前两个循环中的内容。为了能够退出最后的while(1)循环,我们需要在循环结束时检查while-expression而不是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

开始