views:

37

answers:

3

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?

+3  A: 

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.)

Starkey
+2  A: 
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.

nos
+1  A: 

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.

Jens Gustedt