线程同步的障碍
我正在创建 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
线程的运行顺序取决于操作系统。仅仅因为您启动了一个线程并不意味着操作系统会立即运行它。
如果您确实想控制线程的执行顺序,则必须在其中放置某种同步(使用互斥体或条件变量)。
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.)
在
i == n-1
之前,没有任何东西可以阻止该循环的执行。 pthread_create() 只是触发一个要运行的线程。它不会等待它开始或结束。因此,您受到调度程序的支配,调度程序可能会决定继续执行循环,或切换到新创建的线程之一(或在 SMP 系统上同时执行这两种操作)。您还将屏障初始化为
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 和 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, namelystdin
.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