pthread和调用许多线程的正确方法



我有这个代码

我的范围是:程序创建MAX_THREAD线程,在这种情况下是三个线程,每个线程打印线程ID并退出。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#define MAX_THREAD 3
void *thr_func(void *arg);
int main(void) {
    pthread_t thr[MAX_THREAD];
    int i, thr_err;
    /* I expected three threads ... but there is only one */
    for (i=0; i<MAX_THREAD; i++) {
        printf("thread %d: - ", i);
        if ((thr_err = pthread_create(&thr[i],NULL, thr_func, NULL)) != 0) {
            fprintf(stderr, "Err. pthread_create() %sn", strerror(thr_err));
            exit(EXIT_FAILURE);
        }
        if (pthread_join(thr[i], NULL) != 0) {
            fprintf(stderr, "Err. pthread_join() %sn", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
    return(EXIT_SUCCESS);
}
void *thr_func(void *arg)
{
    pthread_t tid = pthread_self();
    printf("TID %lu - Address 0x%xn", tid, (unsigned int)pthread_self());
    pthread_exit((void*)0);
}

输出为:

thread 0: - TID 3075976048 - Address 0xb757ab70
thread 1: - TID 3075976048 - Address 0xb757ab70
thread 2: - TID 3075976048 - Address 0xb757ab70

我不明白为什么只有一个线程!

我对这个声明有疑问:

 pthread_t thr[MAX_THREAD];

我可以创建一个由三个线程组成的数组,或者这只是一个线程????

解决

新代码(我刚刚将 pthread_joiun() 放在 for 循环之外)

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#define MAX_THREAD 3
void *thr_func(void *thr_num);
int main(void) {
    pthread_t thr[MAX_THREAD];
    int i, thr_err;
    for (i=0; i<MAX_THREAD; i++) {
        if ((thr_err = pthread_create(&thr[i],NULL, thr_func, (void*)i)) != 0) {
            fprintf(stderr, "Err. pthread_create() %sn", strerror(thr_err));
            exit(EXIT_FAILURE);
        }
    }
    for (i=0; i<MAX_THREAD; i++) {
        if (pthread_join(thr[i], NULL) != 0) {
            fprintf(stderr, "Err. pthread_join() %sn", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
    return(EXIT_SUCCESS);
}
void *thr_func(void *thr_num)
{
    pthread_t tid;
    if ((tid = syscall(SYS_gettid)) == -1) {
        fprintf(stderr, "Err. syscall() %sn", strerror(errno));
        exit(EXIT_FAILURE);
    }
    printf("thread '%d' - TID %lu - Address 0x%xn",
            (int)thr_num, tid, (unsigned int)tid);
    pthread_exit((void*)0);
}

输出为:

thread '1' - TID 8780 - Address 0x224c
thread '0' - TID 8779 - Address 0x224b
thread '2' - TID 8781 - Address 0x224d

地址和线程 ID 现在不同了。

您可能会获得相同的 TID 和地址,正是因为您在开始下一个线程之前pthread_join()每个线程。pthreads库似乎对回收关联的数据结构有点懒惰(可能是为了提高效率),因此您生成的下一个线程仅使用与前一个线程相同的数据结构。尝试编写两个循环,一个用于创建线程,另一个用于在所有线程创建后执行pthread_join()

我突然想到的一个直接问题是在你的循环中使用了for(i=1; i<=MAX_THREAD; i++)。您的数据结构(pthread_t thr[MAX_THREAD])是 0 索引。因此,运行循环可能是最简单的方法,例如 (i=0; i

其他任何东西似乎都没有损坏。您的代码很奇怪,因为您正在启动每个线程(从执行 main 的线程),然后在继续分叉下一个线程之前通过 pthread_join 阻止其完成。

这并不能解释为什么您的输出每次都显示"线程 0:"...我希望在您当前的程序中看到它从 1 开始,并且在您的循环中也会递增"i"。如果你不做 pthread 生成和连接,你的代码会打印什么?如上所述修复循环绑定后,它是否输出"线程 0:线程 1:线程 2:"

我认为

,在启动新线程之前,旧线程正在退出,因此新线程将获得相同的 TID。尝试通过保持旧线程活动来打开新线程,我相信它会给出不同的 TID。

最新更新