我想将一个简单的一维数组拆分成多个块,每个线程都在一个块上运行。代码看起来像
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
我该如何解决?
相反,将要处理的数据传递给线程 - 传递数组及其长度。使用结构很好地包装它并进行静态类型检查。让一切都变得抽象。
#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
来传递您想要的数据 - 无论是线程的索引还是整个数组的大小。