C 为什么我创建的线程没有按顺序打印?
我有这个计划:C 为什么我创建的线程没有按顺序打印?,c,multithreading,pthreads,race-condition,C,Multithreading,Pthreads,Race Condition,我有这个计划: 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 threa
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 0
My ID is 2
因为我已经添加了互斥锁,所以我认为它可以解决这个问题。我还做错了什么?这与比赛条件有关吗?不,不涉及比赛条件。(my b)i上可能存在争用条件,因为所有线程都访问它。每个线程都以指向i的指针开始。然而,主要的问题是,不能保证线程将启动并运行关键部分,而我将按照您期望的顺序保存您期望的值
我假设您全局声明变量mutex
,并在某个地方调用pthread\u mutex\u init()
对其进行初始化
互斥锁非常好,一次只允许一个线程访问代码的关键部分。因此,您编写的代码创建了所有三个并行运行的线程,但每次只允许一个线程运行以下代码
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
不,不涉及比赛条件。(my b)i上可能存在争用条件,因为所有线程都访问它。每个线程都以指向i的指针开始。然而,主要的问题是,不能保证线程将启动并运行关键部分,而我将按照您期望的顺序保存您期望的值
我假设您全局声明变量mutex
,并在某个地方调用pthread\u mutex\u init()
对其进行初始化
互斥锁非常好,一次只允许一个线程访问代码的关键部分。因此,您编写的代码创建了所有三个并行运行的线程,但每次只允许一个线程运行以下代码
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
这里
id
指向所有线程的同一个主变量i
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
但是变量i
不断被线程后面main
中的两个for
-循环更新。因此,在线程到达printf
点之前,i
的值以及*id
的值可能已经更改
有几种方法可以解决这个问题。最佳方法取决于用例:
i
或使其超出范围之前,请在main
中等待,直到线程发出信号表示它已复制了*id
int-thread\u-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);
只是别忘了在使用完线程后释放线程中的内存。或者在main
中,如果线程无法启动i
适合void*
则可以将其内容作为参数直接传递给线程。为了确保它合适,您可以将其声明为intptr\t
,而不是int
(我们基本上滥用了指针只不过是神奇整数的事实):
void*func(void*arg){
pthread_mutex_lock(&mutex);
//这里我们将指针值解释为整数值
intptr_t id=(intptr_t)arg;
printf(“我的ID是%d\n”,(int)ID);
pthread_mutex_unlock(&mutex);
}
int main(){
intptr\t i;
pthread_t tid[3];
//让我们创建三个线程
对于(i=0;i<3;i++){
//这里我们把'i'的整数值压缩成
//应该拿着一个指针
pthread_create(&tid[i],NULL,func,(void*)i);
}
对于(i=0;i<3;i++){
pthread_join(tid[i],NULL);
}
//这不属于这里!!
//pthread_exit(NULL);
返回0;
}
这里
id
指向所有线程的同一个主变量i
int *id = (int *)arg;
printf("My ID is %d\n" , *id);
但是变量i
不断被线程后面main
中的两个for
-循环更新。因此,在线程到达printf
点之前,i
的值以及*id
的值可能已经更改
有几种方法可以解决这个问题。最佳方法取决于用例:
i
或使其超出范围之前,请在main
中等待,直到线程发出信号表示它已复制了*id
int-thread\u-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);
只是别忘了在使用完线程后释放线程中的内存。或者在main
中,如果线程无法启动i
适合void*
则可以将其内容作为参数直接传递给线程。为了确保它合适,您可以将其声明为intptr\t
,而不是int
(我们基本上滥用了指针只不过是神奇整数的事实):
void*func(void*arg){
pthread_mutex_lock(&mutex);
//这里我们将指针值解释为整数值
intptr_t id=(intptr_t)arg;
printf(“我的ID是%d\n”,(int)ID);
pthread_mutex_unlock(&mutex);
}
int main(){
intptr\t i;
pthread_t tid[3];
//让我们创建三个线程
对于(i=0;i<3;i++){
//这里我们把'i'的整数值压缩成
//应该拿着一个指针
pthread_create(&tid[i],NULL,func,(void*)i);
}
对于(i=0;i<3;i++){
pthread_join(tid[i],NULL);
}
//这不属于这里!!
//pthread_exit(NULL);
返回0;
}
实际上,存在一个竞争条件:
main()
的局部变量i
在没有fir的情况下递增(通过main()
中的for循环)