implement a semaphore

glib, semaphore

Solution

An asynchronous queue can be used as a semaphore:

initialization: GAsyncQueue *queue = g_async_queue_new();

the V operation: g_async_queue_push(queue, GINT_TO_POINTER(1));

the P operation: g_async_queue_pop(queue);

The size of the queue serves as the counter of the semaphore. The second parameter to g_async_queue_push may be any pointer except for NULL. However, if you want to use the semaphore for some consumer/producer task, then sending in a pointer to some data will be useful.

In some cases, a thread pool may fit even better.

Problem

It appears that glib provides mutexes and conditions as thread synchronization primitives, but what about generic semaphores (in the sense that they support the original P and V operations?) Am I correct in understanding a `GCond` as equivalent to a binary semaphore, with `g_cond_signal` being equivalent to `P`, and `g_cond_wait` being equivalent to `V`? But what about semaphores not restricted to a maximum value of 1? I thought of something like this: ``` struct semaphore { int n; GMutex sem_lock; GCond sem_cond; } ``` Where the `P` operation would now look something like this: ``` void semaphore_P (struct semaphore *sem) { g_mutex_lock(sem->sem_lock); while (sem->n == 0) g_cond_wait(sem->sem_cond, sem->sem_lock); --sem->n; g_mutex_unlock(sem->sem_lock); } ``` Is there a simpler way to get at the functionality of pthreads' `sem_wait` and `sem_post` from within glib?

Original source