为什么pthread_self()多次返回相同的id?

时间:2014-06-01 13:53:43

标签: linux multithreading pthreads posix

我试图在for循环中创建一些线程(代表人),并显示作为参数传递的person id以及线程id。人员ID显示为已执行,但线程ID始终相同。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* travelers(void* arg) {
    int* person_id = (int*) arg;
    printf("\nPerson %d was created, TID = %d", *person_id, pthread_self());
}

int main(int argc, char** argv)
{
    int i;
    pthread_t th[1000];

    for (i=0; i < 10; i++) {
        if ((pthread_create(&th[i], NULL, travelers, &i)) != 0) {
            perror("Could not create threads");
            exit(2);
        }
        else {
            // Join thread
            pthread_join(th[i], NULL);
        }
    }
    printf("\n");

    return 0;
}

我得到的输出是这样的:

Person 0 was created, TID = 881035008
Person 1 was created, TID = 881035008
Person 2 was created, TID = 881035008
Person 3 was created, TID = 881035008
Person 4 was created, TID = 881035008
Person 5 was created, TID = 881035008
Person 6 was created, TID = 881035008
Person 7 was created, TID = 881035008
Person 8 was created, TID = 881035008
Person 9 was created, TID = 881035008

我做错了什么?

3 个答案:

答案 0 :(得分:8)

由于一次只运行一个创建的线程,每个新线程都获得与之前完成的ID相同的ID,即只重复使用ID。尝试在循环中创建线程,然后在第二个循环中连接它们。

但是,您必须注意每个线程独立地读取i的内容,这会给您带来不同的麻烦。我将索引作为上下文参数传递,然后将其转换为线程函数内的int。

答案 1 :(得分:1)

这样做,因为它重用了线程ID。线程id在所有正在运行的线程中只是唯一的,但不适用于在不同时间运行的线程;看看你的for循环本质上是做什么的:

for (i = 0 to 10) {
  start a thread;
  wait for termination of the thread;
}

因此程序在任何给定时间只有一个线程运行,一个线程仅在前一个启动线程终止后启动(使用pthread_join())。要使它们同时运行,请使用两个for循环:

for (i = 0 to 10) {
  start thread i;
}
for (i = 0 to 10) {
  wait until thread i is finished;
}

然后你可能会获得不同的线程ID。 (即你将获得不同的线程ID,但是如果printf函数将以不同的方式写出它们取决于你的具体实现/体系结构,特别是如果thread_t本质上是一个int或者不是。例如,它可能是一个long int)

答案 2 :(得分:1)

if ((pthread_create(&th[i], NULL, travelers, &i)) != 0)

如果线程成功创建,则返回0.如果!= 0将返回false,您将执行pthread_join。您正在有效地重复创建一个线程。