开发者

How to initialise a binary semaphore in C

开发者 https://www.devze.com 2023-04-06 04:38 出处:网络
In the man page it appears that even if you initialise a semaphore to a value of one: sem_init(&mySem, 0, 1);

In the man page it appears that even if you initialise a semaphore to a value of one:

sem_init(&mySem, 0, 1);

It 开发者_运维问答could still be incremented to a value greater than 1 with multiple calls to

sem_post(&mySem);

But in this code example the comment seems to think differently:

sem_init(&mutex, 0, 1);      /* initialize mutex to 1 - binary semaphore */

Is it possible to initialise a strictly binary semaphore in C?

Note: The reason for doing this instead of using a mutex in this case is the sem_post and sem_wait may be called by different threads.


If you want a strictly binary semaphore on Linux, I suggest building one out of mutexes and condition variables.

struct binary_semaphore {
    pthread_mutex_t mutex;
    pthread_cond_t cvar;
    bool v;
};

void mysem_post(struct binary_semaphore *p)
{
    pthread_mutex_lock(&p->mutex);
    if (p->v)
        abort(); // error
    p->v = true;
    pthread_cond_signal(&p->cvar);
    pthread_mutex_unlock(&p->mutex);
}

void mysem_wait(struct binary_semaphore *p)
{
    pthread_mutex_lock(&p->mutex);
    while (!p->v)
        pthread_cond_wait(&p->cvar, &p->mutex);
    p->v = false;
    pthread_mutex_unlock(&p->mutex);
}


you can create a wrapper function for sem_post that will check the semaphore value before sem_post().

example:

int semaphore_give(sem_t *sem)
{
    int value, ret;

    if (!sem)
        return -1;
    
    if (sem_getvalue(sem, &value))
        return -1;

    if (value == 0)
        return sem_post(sem);
    return -1;
}


I don't like the implementation of semaphores in Linux but have to use it. To make it simple I decrement sem value till zero with sem_trywait if it is returned one on the first check:

if (sem_trywait(pProcess->sem_id) < 0 && errno != EINTR ) {
    return ERROR;
}
else {
    while (sem_trywait(pProcess->sem_id) == 0);
    return OK;
}

Be careful if sem_post is called too often. You can stuck in the while() clause. In my case it's called no more than once per second.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号