我一直在创建使用POSIX线程来说明并发错误的程序。
我的整体问题是main()线程与pthread_create()
创建的线程之间的区别是什么。我最初的理解是它们几乎相同但是,我从下面的两个程序得到了不同的结果。
要在显示我编写的代码之前展开,我想知道的是:以下内容之间是否存在差异。
int main() {
...
pthread_create(&t1, NULL, worker, NULL);
pthread_create(&t2, NULL, worker, NULL);
...
}
和
int main() {
...
pthread_create(&t1, NULL, worker, NULL);
worker();
...
}
使用完整的示例程序进行扩展。我已经制作了同一个程序的两个版本。它们都具有相同的功能worker()
void *worker(void *arg) {
printf("Entered worker function\n");
int myid;
int data = 999;
pthread_mutex_lock(&gidLock);
myid = gid;
gid++;
printf("myid == %d\n", myid);
pthread_mutex_unlock(&gidLock);
if (myid == 0) {
printf("Sleeping since myid == 0\n");
sleep(1);
result = data;
printf("Result updated\n");
}
return NULL;
}
gid
和data
是初始化为0的全局变量。
以下main()
函数
int main_1() {
pthread_t t1, t2;
int tmp;
/* initialize globals */
gid = 0;
result = 0;
pthread_create(&t1, NULL, worker, NULL);
pthread_create(&t2, NULL, worker, NULL);
pthread_join(t2, NULL);
printf("Parent thread exited worker function\n");
tmp = result;
printf("%d\n", tmp);
pthread_exit((void *) 0);
}
和
int main_2() {
pthread_t t1;
int tmp;
/* initialize globals */
gid = 0;
result = 0;
pthread_create(&t1, NULL, worker, NULL);
worker(NULL);
printf("Parent thread exited worker function\n");
tmp = result;
printf("%d\n", tmp);
pthread_exit((void *) 0);
}
main_1()
Entered worker function
myid == 0
Sleeping since myid == 0
Entered worker function
myid == 1
Parent thread exited worker function
0
Result Updated
main_2()
Entered worker function
myid == 0
Sleeping since myid == 0
Entered worker function
myid == 1
/* program waits here */
Result updated
Parent thread exited worker function
999
编辑:该程序故意有一个并发错误(原子性违规)。通过调用sleep()来尝试强制进行错误的交错来添加延迟。该程序的目的是用于测试软件自动检测并发错误。
我认为main_1()
和main_2()
本质上是相同的程序,当在同一系统上运行时应该导致相同的交错(或者大部分相同的交错;它是不确定的,但是运行同一系统上的相同程序只会探索潜在调度的一小部分,很少偏离[1])。
“所需”输出来自main_1()
我不确定为什么myid == 1
的帖子在main_2()
中停止并且不返回。如果我不得不猜测
感谢您阅读这篇文章,如果有人需要更多信息,我很乐意帮忙。以下是完整源代码的链接。
main_1()
:https://gist.github.com/2942372
main_2()
:https://gist.github.com/2942375
我一直在使用gcc -pthread -lpthread
再次感谢。
[1] S. Park,S。Lu,Y。Zhou。 “CTrigger:揭露隐藏地点的原子性违规行为”