【问题标题】:Barriers for thread syncing线程同步的障碍
【发布时间】:2011-04-16 23:07:19
【问题描述】:

我正在创建 n 个线程,然后在障碍击穿后开始执行。

在全局数据空间中:

int bkdown = 0;

在 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");
}

在线程运行器函数中:

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

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

        ...

 pthread_exit(NULL);
}

预期顺序:

breakdown imminent!
barrier broken down!
breakdown already occurred!

实际顺序: (反复测试)

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

有人可以解释为什么我在"already occurred" 消息之前没有收到"broken down" 消息吗?

【问题讨论】:

    标签: c pthreads barrier


    【解决方案1】:

    线程的运行顺序取决于操作系统。仅仅因为您启动一个线程并不意味着操作系统会立即运行它。

    如果你真的想控制线程的执行顺序,你必须在其中放置某种同步(使用互斥锁或条件变量。)

    【讨论】:

      【解决方案2】:
      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");
      }
      

      i == n-1 之前没有什么能阻止这个循环的执行。 pthread_create() 只是触发要运行的线程。它不会等待它开始或结束。因此,您受调度程序的支配,它可能决定继续执行您的循环,或切换到新创建的线程之一(或在 SMP 系统上同时执行)。

      您还初始化了n 的屏障,因此在任何情况下,在您创建所有线程之前,所有线程都不会越过屏障。

      【讨论】:

        【解决方案3】:

        除了 nos 和 Starkey 的答案之外,您还必须考虑到您的代码中还有另一个经常被忽略的序列化:您正在同一个 FILE 变量上执行 IO,即 stdin

        对该变量的访问在内部是互斥的,您的n+1 线程(包括您的调用线程)访问该互斥的顺序是实现定义的,在您的情况下基本上是随机的。

        因此,您获得printf 输出的顺序就是您的线程通过这些虫洞的顺序。

        【讨论】:

          【解决方案4】:

          您可以通过以下两种方式之一获得预期的订单

          • 创建优先级高于主线程的每个线程。这将确保新线程在创建后立即运行并在屏障上等待。
          • 将“故障迫在眉睫!\n”打印移到 pthread_create() 之前,并在每个 pthread_create() 之后调用使用 sched_yield() 调用。这将安排新创建的线程执行。

          【讨论】:

            猜你喜欢
            • 2021-10-30
            • 2016-03-02
            • 1970-01-01
            • 2016-06-22
            • 2012-01-05
            • 2012-07-26
            • 2014-06-25
            • 2013-06-12
            • 1970-01-01
            相关资源
            最近更新 更多