调用pthread_join()后,C POSIX线程(phead)pthread_create()不工作

nuypyhwy  于 2022-12-22  发布在  其他
关注(0)|答案(1)|浏览(137)

我写了一个线程应用程序的基本例子,它似乎没有像我期望的那样工作。程序应该打印从0到99的数字,但似乎在跳过。我已经追踪到这样一个事实,即在thread_join()循环第一次执行后,下一次,info[k].tid是零。我不知道为什么会发生这种情况。

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

typedef struct {
    pthread_t tid;
    int i;
    int res;
} thread_info;

void *square(void *data) {
    thread_info *info = (thread_info*) data;
    info->res = info->i;
    return NULL;
}

int main(void) {
    int nthread = 2;
    int lim = 100;
    int *results;

    results = calloc(lim, sizeof(int ));
    thread_info *info = calloc(nthread, sizeof(thread_info));

    for (int i=0; i<lim; i++) {
        info[i % nthread].i = i;
        pthread_create(&info[i].tid, NULL, square, info + (i%nthread));

        if (((i+1) % nthread)) {
            continue;
        }

        for (int k=0; k<nthread; k++) {
            pthread_join(info[k].tid, NULL);
        }

        for (int k=0; k<nthread; k++) {
            results[info[k].i] = info[k].res;
        }

        memset(info, 0, sizeof(thread_info) * nthread);
    }

    for (int i=0; i<100; i++) {
        printf("%d\n", results[i]);
    }

    return 0;
}
xeufq47z

xeufq47z1#

编写的代码已损坏:这里

for (int i=0; i<lim; i++) {
  info[i % nthread].i = i;
  pthread_create(&info[i].tid, NULL, square, info + (i%nthread));
  ...

您正在访问info[i].tidi[0, 100)范围内,但info只包含2(nthread)个元素。这是缓冲区溢出。
此处:

for (int k=0; k<nthread; k++) {
    pthread_join(info[k].tid, NULL);
}

您正在加入info[0].tidinfo[1].tid。这对i == 0i == 1有效,但由于上述错误,对i == 3无效。
您希望:

for (int i=0; i<lim; i++) {
        const int slot = i % nthread;
        info[slot].i = i;
        pthread_create(&info[slot].tid, NULL, square, info + slot);

你也应该 * 总是 * 检查所有pthread_*函数的返回值。这样做会节省很多调试时间。
例如,通过此更改,问题变得更加清楚:

for (int k=0; k<nthread; k++) {
  int rc = pthread_join(info[k].tid, NULL);
  if (rc != 0) {
    fprintf(stderr, "pthread_join: %s\n", strerror(rc));
    abort();
  }
}
...

gcc -g -pthread thr.c && ./a.out
pthread_join: No such process
Aborted

相关问题