【问题标题】:pthread and the right way to invoke many threadspthread 和调用多个线程的正确方法
【发布时间】:2012-11-29 17:14:51
【问题描述】:

我有这个代码

我的范围是:程序创建 MAX_THREAD 个线程,在本例中为三个,每个线程打印 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() %s\n", strerror(thr_err));
            exit(EXIT_FAILURE);
        }

        if (pthread_join(thr[i], NULL) != 0) {
            fprintf(stderr, "Err. pthread_join() %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

    return(EXIT_SUCCESS);
}

void *thr_func(void *arg)
{
    pthread_t tid = pthread_self();
    printf("TID %lu - Address 0x%x\n", 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() %s\n", 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() %s\n", 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() %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    printf("thread '%d' - TID %lu - Address 0x%x\n",
            (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 现在不同了。

【问题讨论】:

  • 请注意,您的代码不可移植。将pthread_t 转换为unsigned int 的结果是完全不可预测的。 (在某些平台上,您可能有两个具有不同 ID 的线程,但在转换为 unsigned int 时看起来相同。同一个线程甚至可能有多个这样的结果,因此不相等的值甚至不能证明不同的线程。那是为什么你需要pthread_equal。)
  • 是的,我知道,这仅用于测试线程调用,我的下一个代码将使用 syscall(SYS_gettid) 来管理 TID。非常感谢

标签: linux multithreading pthreads


【解决方案1】:

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

【讨论】:

  • 非常感谢,在 for 循环之外使用 pthread_join() 效果很好。
【解决方案2】:

我突然想到的一个直接问题是在循环中使用 for (i=1; i

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

这并不能解释为什么您的输出每次都显示“线程 0:”......我希望在您当前的程序中看到这个以 1 开头,并且在您的循环中也会增加“i”。如果您不进行 pthread 生成和加入,您的代码会打印什么?如上所述修复循环绑定后,它是否输出“线程0:线程1:线程2:”

【讨论】:

  • 问题不是线程1,2等...问题是相同的TID和相同的地址。
  • 好的,我明白了!现在的代码是正确的,但问题仍然存在。
  • 为什么 TID 相等?为什么地址相等?这是我不明白的。
  • 固定循环边界后,可以剪切粘贴程序输出吗?
  • 我的程序输出是我第一篇文章的输出。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2018-10-13
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多