Причина, по которой вы получаете одинаковый TID для каждого потока, заключается в том, что вы вызываете syscall(SYS_gettid)
из основного потока каждый раз, а не из созданного вами нового потока. Вам нужно вызвать его изнутри функции потока, а затем предоставить способ передать информацию обратно в основной поток, если он там нужен.
В качестве примера один из способов сделать это (некоторые проверка ошибок опущена):
Создать-структуру, чтобы держать мьютекс, состояние, в TID, и флаг, указывающий, когда TID является действительным.
struct s_threadId {
pthread_mutex_t mtx; /* mutex & condition to allow main thread to
wait for the new thread to set its TID */
pthread_cond_t cond; /* '' */
pid_t id; /* to hold new thread's TID */
int ready; /* to indicate when 'id' is valid, in case
the condition wait gets interrupted */
};
Затем измените функцию резьбы для блокировки, множество, и сигнал (и переместите его так, чтобы это заявление видна перед темspawnThreads()
):
void *foo(void *arg)
{
struct s_threadId *thId = arg;
/* Lock mutex... */
pthread_mutex_lock(&thId->mtx);
/* Get and save TID and ready flag.. */
thId->id = syscall(SYS_gettid);
thId->ready = 1;
/* ..and signal main thread that we're ready */
pthread_cond_signal(&thId->cond);
/* ..then unlock when we're done. */
pthread_mutex_unlock(&thId->mtx);
/* ... */
return NULL;
}
... и изменить spawnThreads
функцию для инициализации/очистки элементов структуры и получения TID после того, как нить устанавливает его:
void spawnThreads(unsigned int n)
{
pthread_t thread; /* reused for each thread, since they run 1 at a time */
/* struct to pass back TID */
struct s_threadId threadId;
pthread_cond_init(&threadId.cond, NULL); /* init condition */
pthread_mutex_init(&threadId.mtx, NULL); /* init mutex */
int i;
for (i = 0; i < n; i++) {
/* lock mutex *before* creating the thread, to make the new thread
wait until we're ready before signaling us */
pthread_mutex_lock(&threadId.mtx);
/* clear ready flag before creating each thread */
threadId.ready = 0;
/* create threads and pass address of struct as argument */
if (pthread_create(&thread, NULL, foo, &threadId)) {
printf("pthread error!\n");
} else {
/* Wait on the condition until the ready flag is set */
while (!threadId.ready) {
pthread_cond_wait(&threadId.cond, &threadId.mtx);
}
/* Now we have the TID... */
printf("%d %d\n", i, threadId.id);
printf("I just created thread %d\n", i);
}
/* ..and unlock the mutex when done. */
pthread_mutex_unlock(&threadId.mtx);
pthread_join(thread, NULL);
}
/* When we're completely done with the struct we need to clean up the
mutex and condition variable */
pthread_mutex_destroy(&threadId.mtx);
pthread_cond_destroy(&threadId.cond);
}
В ab ove, мьютекс и ожидание состояния необходимы, чтобы убедиться, что основной поток не пытается распечатать TID до тех пор, пока новый поток не сможет его установить. Основной поток запускает новый, а затем ждет, и новый сигнал потока, когда он будет хранить TID, поэтому основной поток может продолжаться.
Это не ваш фактический код. Ref 'pthread_creation' – Erik
Также:' (void * (*) (void *)) 'what-the-cast ?! – Kninnug
Вы вызываете 'syscall (SYS_gettid)' из основного потока, а не за созданные вами новые потоки ... – Dmitri