Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to avoid polling in pthreads

I've got some code that currently looks like this (simplified)

/* instance in global var *mystruct, count initialized to 0 */
typedef struct {
    volatile unsigned int count;
} mystruct_t;

pthread_mutex_t mymutex; // is initialized

/* one thread, goal: block while mystruct->count == 0 */
void x(void *n) {
    while(1) {
        pthread_mutex_lock(&mymutex);
        if(mystruct->count != 0) break;
        pthread_mutex_unlock(&mymutex);       
    }
    pthread_mutex_unlock(&mymutex);
    printf("count no longer equals zero");
    pthread_exit((void*) 0)
}

/* another thread */
void y(void *n) {
    sleep(10);
    pthread_mutex_lock(&mymutex);
    mystruct->count = 10;
    pthread_mutex_unlock(&mymutex);
}

This seems inefficient and wrong to me--but I don't know a better way of doing it. Is there a better way, and if so, what is it?

like image 764
Aaron Yodaiken Avatar asked Dec 27 '22 19:12

Aaron Yodaiken


2 Answers

Condition variables allow you to wait for a certain event, and have a different thread signal that condition variable.

You could have a thread that does this:

for (;;)
{
   if (avail() > 0)
      do_work();
   else
      pthread_cond_wait();
}

and a different thread that does this:

for (;;)
{
   put_work();
   pthread_cond_signal();
}

Very simplified of course. :) You'll need to look up how to use it properly, there are some difficulties working with condition variables due to race conditions.

However, if you are certain that the thread will block for a very short time (in order of µs) and rarely, using a spin loop like that is probably more efficient.

like image 177
Maister Avatar answered Jan 12 '23 07:01

Maister


A general solution is to use a POSIX semaphore. These are not part of the pthread library but work with pthreads just the same.

Since semaphores are provided in most other multi-threading APIs, it is a general technique that may be applied perhaps more portably; however perhaps more appropriate in this instance is a condition variable, which allows a thread to pend on the conditional value of a variable without polling, which seems to be exactly what you want.

like image 43
Clifford Avatar answered Jan 12 '23 08:01

Clifford