线程同步的障碍

发布于 2024-09-25 00:07:33 字数 904 浏览 6 评论 0原文

我正在创建 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!!

有人可以解释一下原因吗在“已经发生” 消息之前我没有收到“已损坏” 消息?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

葬心 2024-10-02 00:07:33

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

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

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

可爱咩 2024-10-02 00:07:33
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,因此在任何情况下,在您创建所有线程之前,没有任何线程可以通过屏障。

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.

伴随着你 2024-10-02 00:07:33

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

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

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

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.

梦里泪两行 2024-10-02 00:07:33

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

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

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文