我正在创建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!!
有人可以解释为什么我在"broken down"
消息之前没有收到"already occurred"
消息吗?
答案 0 :(得分:3)
运行线程的顺序取决于操作系统。仅仅因为你启动一个线程并不意味着操作系统会立即运行它。
如果你真的想控制执行线程的顺序,你必须在那里放置某种同步(使用互斥锁或条件变量。)
答案 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
的障碍,所以无论如何,在你创造所有这些线程之前,所有线程都不会越过障碍。
答案 2 :(得分:1)
除了nos和Starkey的答案之外,您还必须考虑到代码中有另一个经常被忽略的序列化:您在相同的FILE
变量上执行IO,即{{1} }。
对该变量的访问是内部互斥的,并且stdin
线程(包括您的调用线程)访问该互斥锁的顺序是实现定义的,在您的情况下基本上是随机的。
因此,获得n+1
输出的顺序是线程通过这些虫洞的顺序。
答案 3 :(得分:0)
您可以通过两种方式之一获得预期订单