c - How to block on a semaphore until its value is positive -


i want use semaphores make threads block until semaphores become positive; when threads block on semaphore, unblock on first sem_post called on it, regardless of value of semaphore afterwards.

the situation follows:

  1. semaphore set -1.
  2. a thread started wait 5 seconds before posting semaphore.
  3. once 5 seconds pass, thread posts semaphore.
  4. the semaphore's value 0, main process unblocks anyway.

here code demonstrating situation:

/**  * testing whether sem_post on semaphore unblocks threads  *     despite still being negative.  **/ #include <semaphore.h> #include <pthread.h> #include <stdio.h> #include <unistd.h>  sem_t sem;  void *proc(void *arg) {     sleep(5);     puts("posting");     sem_post(&sem); }  void setup() {     pthread_t pt;     pthread_create(&pt, 0, proc, 0); }  int main(int argc, char **argv) {     sem_init(&sem, 0, -1);      setup();      sem_wait(&sem);      return 0; } 

i have found crude way overcome issue wrapping sem_wait in busy loop checks if semaphore's value 0, seems wrong way approach this.

is there more elegant way block on semaphore until value positive (not 0, nor negative)?

you can't initialize semaphore -1 because api initialize takes unsigned values.

int sem_init(sem_t *sem, int pshared, unsigned int value);
the open group

probably, using -1 caused value larger sem_value_max passed sem_init(), , initialization failed. should check return code, , if errno got set einval.

the sem_init() function fail if:

  • [einval] value argument exceeds sem_value_max.
  • ...
    the open group

  • if want threads block on semaphore on first call sem_wait, initialize semaphore 0 instead.

    if system supports it, can use sem_getvalue find number of waiters on semaphore if count 0.

    if sem locked, value returned sem_getvalue() either 0 or negative number absolute value represents number of processes waiting semaphore @ unspecified time during call.
    the open group

    an implementation allowed choose behavior want, works if system supports it. linux, example, not support it, since chooses return 0 if semaphore count 0.

    if 1 or more processes or threads blocked waiting lock semaphore sem_wait(3), posix.1 permits 2 possibilities value returned in sval: either 0 returned; or negative number absolute value count of number of processes , threads blocked in sem_wait(3). linux adopts former behavior.
    man7.org

    probably reliable way implement want use mutual exclusion variable, condition variable, , counter.

    extern pthread_mutex_t lock; extern pthread_cond_t queue; extern atomic_uint waiters;  /* assume waiters 0 */ pthread_mutex_lock(&lock); ++waiters; while (my_status() == waiting) {     pthread_cond_wait(&queue, &lock); } --waiters; pthread_mutex_unlock(&lock); 

    Comments

    Popular posts from this blog

    java - nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet Hibernate+SpringMVC -

    sql - Postgresql tables exists, but getting "relation does not exist" when querying -

    asp.net mvc - breakpoint on javascript in CSHTML? -