Understanding posix barrier mechanism

∥☆過路亽.° 提交于 2019-12-22 09:43:07

问题


Here is piece (very simplified, with global var's and other "smells") of C code, which uses posix barrier primitive to sincronize thread start.

#include <pthread.h>
#include <stdio.h>

pthread_barrier_t barrier;

void* thread_func(void* aArgs)
{
  pthread_barrier_wait(&barrier);

  printf("Entering thread %p\n", (void*)pthread_self());
  int i;
  for(i = 0 ; i < 5; i++)
    printf("val is %d in thread %p \n", i, (void*)pthread_self());
}

int main()
{
  pthread_t thread_1, thread_2;
  pthread_barrier_init(&barrier, NULL, 2);

  pthread_create(&thread_1, NULL, (void*)thread_func, NULL);
  printf("Thread %p created\n", (void*)thread_1);

  usleep(500);

  pthread_create(&thread_2, NULL, (void*)thread_func, NULL);
  printf("Thread %p created\n", (void*)thread_2);

  pthread_join(thread_1, NULL);
  pthread_join(thread_2, NULL);

  pthread_barrier_destroy(&barrier);

  return 0;
}

I can't understand, why "Entering thread ..." string occurs not simultaneously in the output? When i run above programm, usually get alike output:

Thread 0xb74fdb40 created
Thread 0xb6cfcb40 created
Entering thread 0xb6cfcb40
val is 0 in thread 0xb6cfcb40 
val is 1 in thread 0xb6cfcb40 
val is 2 in thread 0xb6cfcb40 
val is 3 in thread 0xb6cfcb40 
val is 4 in thread 0xb6cfcb40 
Entering thread 0xb74fdb40
val is 0 in thread 0xb74fdb40 
val is 1 in thread 0xb74fdb40 
val is 2 in thread 0xb74fdb40 
val is 3 in thread 0xb74fdb40 
val is 4 in thread 0xb74fdb40 

What i expect, is simultaneously starting of two threads, and appearing of "Entering thread ..." strings in sequence in the output. Compile it with: gcc barrier.c -pthread

What i'm doing wrong with that?


回答1:


What your barrier is doing is preventing Thread 1 from producing any output before Thread 2 is created.

After both threads are created, both cross the barrier and are unblocked. After that you are not asserting any control as to how they are interleaved. So, thread 1 happens to get its time slice and produces all its output; then thread 2 gets its time slice and produces all its output.

Try moving the barrier after the "Enter" output to get a better understanding.




回答2:


All the barrier does is ensure that neither thread can return from the barrier wait call before the other thread has entered it. There is no ordering relationship between the subsequent output except that each individual stdio call is atomic. The fact that you're seeing all the output for one thread before all the output for the other is simply a consequence of scheduling and/or which thread succeeds in getting the internal mutex in stdout first on each try (once it's gotten it on one and the other thread goes to sleep waiting for the mutex, the first thread has an advantage re-acquiring this mutex first again).

If you want to see output interleaved, add another call to pthread_barrier_wait on your barrier immediately before or after each call to printf.

You would also be statistically much more likely to see interleaving by mere chance if you increased the number of output lines from 5 to 10000 or so.



来源:https://stackoverflow.com/questions/28663622/understanding-posix-barrier-mechanism

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!