如何在c中创建信号量?

问题描述 投票:4回答:1

我正在尝试重新创建“ Blackbox”库。在我的CS类中,当我们应该使用信号量时(在纸上最终版本中),我们得到了一个“ sem.h”文件。有3个函数,一个用于创建带有初始令牌数量的新信号量,一个用于从信号量中取出令牌,另一个用于将令牌放入信号量中的功能。为0时,使用阻塞功能的任何线程都必须等待令牌。

为了更好地理解,我一直在尝试根据要求执行单个功能的某些考试来尝试重新创建此sem.h和sem.c。由于所有这些操作都打算在纸上完成,因此不会编译,但我觉得我非常接近UPDATE它现在可以编译,我更新了代码,但是我还没有时间测试功能,我还没有实现Corret错误处理,正如另一位评论者指出的那样。我希望我会尽快对其进行测试,随着我的病情不断更新sem.h

typedef struct SEM SEM;
struct SEM *semCreate(int);
void P(struct SEM*); //tokens--
void V(struct SEM*); //tokens++

sem.c

#include "sem.h"
#include <pthread.h>
#include <errno.h>
typedef struct SEM{
    volatile int val; //number of tokens
    pthread_mutex_t m;
    pthread_cond_t c;
}SEM;


/*create new semaphore with #initVal tokens */
SEM *semCreate(int initVal){
    SEM *sem = malloc(sizeof(SEM));
    sem->val=initVal;
    errno = 0;
    if((errno = pthread_mutex_init(&sem->m,NULL))!=0){
        return NULL;
    }
    if((errno = pthread_cond_init(&sem->c,NULL))!=0){
        return NULL;
    }
    return sem;
}
//take a token from the semaphore
void P(SEM *sem){
    if((errno = pthread_mutex_lock(&sem->m))!=0){
        return;
    }
    while(sem->val <=0){
        if((errno=pthread_cond_wait(&sem->c,&sem->m))!=0){
            pthread_mutex_unlock(&sem->m);
            return;
        }
        sem->val--;
        if(errno = pthread_mutex_unlock(&sem->m)!=0)return;
    }
}
//put a token into the semaphore
void V(SEM *sem){
    if((errno = pthread_mutex_lock(&sem->m))!=0){
        return;
    }

    sem-> val++;

    if((errno = pthread_cond_broadcast(&sem->c))!=0)return;
    if((errno=pthread_mutex_unlock(&sem->m)!=0)) return;
}

//destroy a semaphore

void semDestroy(SEM* sem){
    free(sem);
}

如果不清楚这是为了什么:函数应限制有多少线程可以同时访问一段代码例子

//global
static SEM *sem = semCreate(1);
/.../
//critical segment in threadfunction
P(sem);
doReadAndWriteGlobalList();
V(sem);

第一个线程通过P()后,对P的任何后续调用都将无法传递它,直到在同一时间调用V为止

edit现在,只要有时间测试不正确的代码,我就摆脱了编译器错误

c struct semaphore
1个回答
1
投票

您不需要静态变量。您想在每次调用semCreate时创建一个新对象(内存分配)。因此,

static SEM *sem ={
    .val=initVal
};

应该是

SEM *sem = malloc(sizeof(SEM));
sem->val = initVal;

完成操作后,别忘了释放信号量。

(可能还有其他问题。我只是在回答一个被问到的问题。)


推荐问答