[英]Why are my threads I created not printed in order?
我有这个程序:
void *func(void *arg) {
pthread_mutex_lock(&mutex);
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
pthread_mutex_unlock(&mutex);
}
int main() {
int i;
pthread_t tid[3];
// Let us create three threads
for (i = 0; i < 3; i++) {
pthread_create(&tid[i], NULL, func, (void *)&i);
}
for (i = 0; i < 3; i++) {
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
return 0;
}
我希望它能输出以下内容:
My ID is 0
My ID is 1
My ID is 2
但是我得到的是随机输出,例如:
My ID is 0
My ID is 0
My ID is 2
由于我已经添加了互斥锁,所以我认为这可以解决问题。 我还做错了什么? 这与种族状况有关吗?
在此, id
指向所有线程的main中相同的变量i
。
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
但是变量i
经常被线程后面的main
的两个for
-loops更新。 因此,在线程到达printf
的点之前, i
的值以及*id
的值可能已经更改。
有几种解决方法。 最佳方法取决于用例:
i
或使其超出范围之前,先在main
等待线程发出信号,表明它已复制*id
。 int thread_id[]
,然后像下面那样创建线程: pthread_create(&tid[i], NULL, func, &thread_id[i]);
malloc
一些内存并使用i
的副本对其进行初始化:
int *thread_id = malloc(sizeof(*thread_id)); *thread_id = i pthread_create(&tid[i], NULL, func, thread_id);
只是不要忘记在使用完线程后将其free
到线程中。 或者在main
线程中,如果线程无法启动。
如果i
适合一个void *
可以将其内容直接作为参数传递给线程。 为了确保它合适,可以将其声明为intptr_t
而不是int
(我们基本上滥用了指针不过是魔术整数这一事实):
void *func(void *arg) { pthread_mutex_lock(&mutex); // Here we interpret a pointer value as an integer value intptr_t id = (intptr_t )arg; printf("My ID is %d\\n" , (int)id); pthread_mutex_unlock(&mutex); } int main() { intptr_t i; pthread_t tid[3]; // Let us create three threads for (i = 0; i < 3; i++) { // Here we squeeze the integer value of `i` into something that is // supposed to hold a pointer pthread_create(&tid[i], NULL, func, (void *)i); } for (i = 0; i < 3; i++) { pthread_join(tid[i], NULL); } // This does not belong here !! // pthread_exit(NULL); return 0; }
不,不涉及比赛条件。 (my b)i上可能存在竞争状况,因为所有线程都访问它。 每个线程都以指向i的指针开始。 但是,主要问题是,不能保证在我按您期望的顺序保存您期望的值时,线程将启动并运行关键部分。
我假设您全局声明了变量mutex
,并在某处调用pthread_mutex_init()
进行了初始化。
互斥体很棒,一次只允许一个线程访问关键的代码部分。 因此,您编写的代码创建了所有三个线程以并行运行,但一次只允许一个线程运行以下代码。
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.