gpt4 book ai didi

C - 创建 n 个线程

转载 作者:可可西里 更新时间:2023-11-01 11:49:22 26 4
gpt4 key购买 nike

我正在研究以下功能。这个函数应该创建 n 个线程。它还应该打印子线程的 tid。但此刻我有点困惑。当我执行它时,例如我创建了 5 个线程,它始终返回相同的 tid。据我了解,tid 是调用者的线程 ID。是同一个调用者调用了所有这些线程还是我做错了什么。这是代码:

void spawnThreads( unsigned int n) {
int threads = n, ret = -1;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
pid_t tid;
int i;
for(i = 0; i < threads; i++) {
ret = pthread_creation(&thread[i], NULL, (void *(*)(void *)) foo, NULL); // foo does not do anything

if( ret != 0) {
printf("pthread error!\n");
}

tid = syscall(SYS_gettid);
printf("%d %d\n", i, tid);
printf("I just created thread %d\n", i);

pthread_join(thread[i],NULL);
}

void * foo(void) {
return NULL;
}

例如,我得到以下输入的 spawnThreads(4)以下输出:

 0 2411
I just created thread 0

1 2411
I just created thread 1

2 2411
I just created thread 2

3 2411
I just created thread 3

总而言之,函数应该打印>i< >tid<>tid<表示 child 的TID,>i<从1到n。

但为什么我得到四次相同的 tid?我做错什么了?如果有人能向我解释哪里出了问题,我将不胜感激。

最佳答案

您为每个线程获得相同 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);
}

在上面,需要互斥锁和条件等待来确保主线程在新线程有机会设置它之前不会尝试打印 TID。主线程启动新线程,然后等待,新线程在完成存储 TID 后发出信号,以便主线程可以继续。

关于C - 创建 n 个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20276010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com