获取逻辑线程ID号

问题描述 投票:0回答:1

我想将一个简单的一维数组拆分成多个块,每个线程都在一个块上运行。代码看起来像

void* thread_func(void* arg) {
    unsigned start_index = *((int*) arg);
    unsigned array_size = *((int*) arg + 1);
    printf("tid=%llu start_index=%lu array_size=%lu\n", syscall(SYS_gettid), start_index,array_size);
    for (int i = start_index; ???)   // <-------
    pthread_exit(NULL);
}

int main(int argc, char* argv[]) {
    unsigned array_size = 4000000000;
    int thread_count = 4;

    data = (unsigned*) malloc(array_size * sizeof(int));
    if (data == NULL) {
        fprintf(stderr, "Error: failed to allocate memory for the array.\n");
        exit(EXIT_FAILURE);
    }
    
    pthread_t threads[thread_count];
    int thread_args[thread_count][4];
    for (int i = 0; i < thread_count; i++) {
        // generate a random starting index for the thread
        thread_args[i][0] = (array_size/thread_count)*i;
        thread_args[i][1] = array_size;
    }

    for (int i = 0; i < thread_count; i++) 
        pthread_create(&threads[i], NULL, thread_func, (void*) &thread_args[i]);

    for (int i = 0; i < thread_count; i++)
        pthread_join(threads[i], NULL);
    
    return 0;
}

对于具有 4B 个元素和 4 个线程的数组。所以块是:

0:999999999
1000000000:1999999999
2000000000:2999999999
3000000000:3999999999

但是我得到的线程ID不在[0:3]的范围内。因此,线程函数循环无法正常工作。

我得到的输出是

tid=16496 start_index=0 array_size=4000000000
tid=16497 start_index=1000000000 array_size=4000000000
tid=16498 start_index=2000000000 array_size=4000000000
tid=16499 start_index=3000000000 array_size=4000000000

我该如何解决?

c pthreads
1个回答
2
投票

相反,将要处理的数据传递给线程 - 传递数组及其长度。使用结构很好地包装它并进行静态类型检查。让一切都变得抽象。

#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
void stuff_to_do();

void process_your_array(int *array, size_t size) {
    for (size_t i = 0; i < size; ++i) { 
       stuff_to_do();
    }
}

struct MyThreadData {
   int *array;
   size_t size;
};

void *thread_func(void *arg) {
    // The thread only sees it's own chunk.
    const struct MyThreadData *mydata = arg;
    // Also, easy to unit test.
    process_your_array(mydata->array, mydata->size);
    return 0;
}

int main(int argc, char* argv[]) {
    const size_t array_size = 4000000000;
    int *array = malloc(array_size * sizeof(*array));
    // Do not use VLA.
    enum { THREAD_COUNT = 4 };
    // 4 threads, 4 datas.
    pthread_t threads[THREAD_COUNT];
    struct MyThreadData threaddata[THREAD_COUNT];
    // Make sure it is even, or TODO: handle uneven case.
    static_assert(array_size % THREAD_COUNT == 0, "");
    for (size_t i = 0; i < THREAD_COUNT; i++) {
        // generate a random starting index for the thread
        threaddata[i] = (struct MyThreadData){
            .array = &array[i * array_size / THREAD_COUNT],
            .size = array_size / THREAD_COUNT,
        };
    }
    for (size_t i = 0; i < THREAD_COUNT; i++) {
        pthread_create(&threads[i], NULL, thread_func, &threaddata[i]);
    }
    for (size_t i = 0; i < THREAD_COUNT; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

以同样的方式,您可以通过将任何数据添加到

MyThreadData
来传递您想要的数据 - 无论是线程的索引还是整个数组的大小。

© www.soinside.com 2019 - 2024. All rights reserved.