Question

I'm creating n threads & then starting then execution after a barrier breakdown.

In global data space:

int bkdown = 0;

In main():

pthread_barrier_init(&bar,NULL,n);

for(i=0;i<n;i++)
{
pthread_create(&threadIdArray[i],NULL,runner,NULL);
if(i==n-2)printf("breakdown imminent!\n");
if(i==n-1)printf("breakdown already occurred!\n");
}

In thread runner function:

void *runner(void *param)
{
 pthread_barrier_wait(&bar);

 if(bkdown==0){bkdown=1;printf("barrier broken down!\n");}

        ...

 pthread_exit(NULL);
}

Expected order:

breakdown imminent!
barrier broken down!
breakdown already occurred!

Actual order: (tested repeatedly)

breakdown imminent!
breakdown already occurred!
barrier broken down!!

Could someone explain why the I am not getting the "broken down" message before the "already occurred" message?

Was it helpful?

Solution

for(i=0;i<n;i++)
{
pthread_create(&threadIdArray[i],NULL,runner,NULL);
if(i==n-2)printf("breakdown imminent!\n");
if(i==n-1)printf("breakdown already occurred!\n");
}

Nothing stops this loop from executing until i == n-1 . pthread_create() just fires off a thread to be run. It doesn't wait for it to start or end. Thus you're at the mercy of the scheduler, which might decide to continue executing your loop, or switch to one of the newly created threads (or do both, on a SMP system).

You're also initalizing the barrier to n, so in any case none of the threads will get past the barrier until you've created all of them.

OTHER TIPS

The order in which threads are run is dependent on the operating system. Just because you start a thread doesn't mean the OS is going to run it immediately.

If you really want to control the order in which threads are executed, you have to put some kind of synchronization in there (with mutexes or condition variables.)

In addition to the answers of nos and Starkey you have to take into account that you have another serialization in your code that is often neglected: you are doing IO on the same FILE variable, namely stdin.

The access to that variable is mutexed internally and the order in which your n+1 threads (including your calling thread) get access to that mutex is implementation defined, take it basically as random in your case.

So the order in which you get your printf output is the order in which your threads pass through these wormholes.

You can get the expected order in one of two ways

  • Create each thread with a higher priority than the main thread. This will ensure that new thread will run immediately after creation and wait on the barrier.
  • Move the "breakdown imminent!\n" print before the pthread_create() and call use a sched_yield() call after every pthread_create(). This will schedule the newly created thread for execution.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top