krb
krb

Reputation: 16315

Multithreaded spin lock?

My daemon initializes itself in four different threads before it starts doing its things. Right now I use a counter which is incremented when a thread is started and decremented when it is finished. When the counter hits 0 I call the initialization finished callback.

Is this the preferred way to do it, or are there better ways? I'm using POSIX threads (pthread) and I just run a while cycle to wait for the counter to hit 0.

Edit: pthread_barrier_* functions are not available on my platform although they do seem to be the best choice.

Edit 2: Not all threads exit. Some initialize and then listen to events. Basically the thread needs to say, "I'm done initializing".

Upvotes: 3

Views: 596

Answers (6)

janneb
janneb

Reputation: 37198

So, what happens if one thread finishes initialization before any of the others begin?

So one way to do it

  1. initialize an atomic counter to 0
  2. when each thread is done with init, increment counter and retrieve the value atomically. If you use GCC, you can use __sync_add_and_fetch()
  3. If the retrieved counter value < N_threads, block on a pthread condition variable.
  4. If the retrieved counter value == N_threads, init phase is done, signal the condition and continue.

Upvotes: 0

crazyscot
crazyscot

Reputation: 11989

Rather than spinning, use the pthread mutex/condvar primitives. I'd suggest a single mutex to protect both the count of threads outstanding, and the condvar.

The main loop looks like this:

acquire mutex
count=N_THREADS;
start your N threads
while (1) {
  if (count==0) break;
  cond_wait(condvar);
}
release mutex

And when each thread is ready it would do something like this:

acquire mutex
count--
cond_signal(condvar)
release mutex

(EDIT: I have assumed that the threads are to keep going once they have done their initialisation stuff. If they are to finish, use pthread_join as others have said.)

Upvotes: 3

Julio Guerra
Julio Guerra

Reputation: 5661

A barrier is what you need. They were created for that, when you need to "meet up" at certain points before continuing. See pthread_barrier_*

Upvotes: 7

unwind
unwind

Reputation: 399793

That sounds ... weird. Shouldn't you just be using pthread_join() to wait for the threads to complete? Maybe I don't understand the question.

Upvotes: 3

user405725
user405725

Reputation:

As Klas Lindbäck pointed out in his answer, joining threads is a preferred way to go. In case your threads are not exiting (i.e. are part of the reusable pool etc.), the logic sounds good. The only thing is that using counter without any synchronisation is dangerous. You have to use either mutex with condition or atomic integer. I'd recommend using mutex + condition if you don't want to spin on atomic counter in the thread that waits for initialisation to finish.

Upvotes: 0

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33273

pthread_join is the preferred way to wait for pthreads.

Upvotes: 3

Related Questions