在多线程C程序错误线程ID? [英] Wrong thread IDs in a multithreaded C program?
问题描述
我是新的C到多线程,我有这个问题。我写了下面code:
I am new to multithreading in C and I had this question. I wrote the following code:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
int main()
{
int i=0;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
pthread_t thread[5];
for (i=0;i<5;i++)
pthread_create(&thread[i],&attr,test,&i);
for (i=0;i<5;i++)
pthread_join(thread[i],NULL);
return 0;
}
我
为什么会像值:
Why do I get values like:
The thread 0 has started.
The thread 0 has started.
The thread 5 has started.
The thread 5 has started.
The thread 0 has started.
The thread 0 has finished.
The thread 0 has finished.
The thread 5 has finished.
The thread 5 has finished.
The thread 0 has finished.
或
The thread 1 has started.
The thread 2 has started.
The thread 5 has started.
The thread 4 has started.
The thread 0 has started.
The thread 1 has finished.
The thread 2 has finished.
The thread 5 has finished.
The thread 4 has finished.
The thread 0 has finished.
甚至是:
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
等等,当我有望获得:
etc, when I expected to get:
The thread 0 has started.
The thread 1 has started.
The thread 2 has started.
The thread 3 has started.
The thread 4 has started.
The thread 0 has finished.
The thread 1 has finished.
The thread 2 has finished.
The thread 3 has finished.
The thread 4 has finished.
只有当我把 usleep(10)
在 thread_create
做我得到一些正常的值。
Only when I put usleep(10)
after thread_create
do I get some "normal" values.
我编译和运行code此code ::在Unix块。
I compiled and run this code in Code::Blocks on Unix.
推荐答案
请注意,您在传递 I
的地址作为参数传递给你的线程:
Notice that you are passing in the address of i
as a parameter to your threads:
pthread_create(&thread[i],&attr,test,&i);
这意味着,所有的线程会被读取相同的变量 I
,以确定他们是哪个线程。也就是说,所有五个线程将看同样的变量来确定自己的线程号。因此,当值 I
在为
循环增值,所有的线程会感觉到自己的线程数更改为使用的新值 I
。这就是为什么你会看到,有时5上来如线程数,也说明了事实,你经常逃课号码或看到太多的重复。
This means that all of your threads will be reading the same variable i
to determine which thread they are. That is, all five threads will look at the same variable to determine their thread number. Consequently, as the value of i
increments in your for
loop, all the threads will perceive their thread number changing to use the new value of i
. This is why you're sometimes seeing 5 come up as the thread number, and also explains the fact that you're often skipping numbers or seeing far too many duplicates.
要解决这个问题,你就需要给每个线程自己的拷贝我
。例如,你可以做这样的事情:
To fix this, you will need to give each thread their own copy of i
. For example, you could do something like this:
int* myI = malloc(sizeof(int));
*myI = i;
pthread_create(&thread[i], &attr, test, myI);
,然后让线程终止之前释放指针:
And then have the threads free the pointer before terminating:
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
free(a);
}
另外,你可以投 I
到无效*
,并通过在:
pthread_create(&thread[i],&attr,test, (void*)i);
如果你这样做,你将不得不线程投下他们的论点直接回 INT
,而不是为int *
:
If you do this, you would then have the threads cast their arguments directly back to int
, not to int*
:
void* test(void *a)
{
int i = (int)a;
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
希望这有助于!
这篇关于在多线程C程序错误线程ID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!