您似乎拥有 Java 背景(或 D),正如您所写的 int [10] A。您可以将其理解为 A 是 10 个整数的数组的变量 类型对象。但是在 C 语言中,这些事情有点不同。在 C 语言中,只有单独的原始变量,它们可以排列成一组连续的内存,这就是所谓的数组。这就是选择语法int A[10]; 的原因,这意味着:A 是一个指向整数的指针,指向自动分配的10 个整数的存储的开头。
您的程序的下一个问题,尽管编译器不会报告它正在通过void* 类型传递一个整数。在 C 中,每个指针都可以转换为某个整数,但并非所有整数值都成为指针。 C 中的指针是抽象的东西:大多数实现选择使用内存地址作为它们的整数表示。但是通过单射 LUT 映射它们同样有效。因此,某些整数值可能无法映射到指针,因此无法正确传输。你真的应该传递一个真正的指针。
您对线程的使用也不是最理想的。在您的情况下,您正在疯狂地破坏缓存行,并且切换开销会消耗掉任何并行化增益。根据经验,您应该创建不超过 'number of CPU cores' + 2 个线程。考虑到所有这些,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* some prime number, so show what happens with uneven work sizes */
#define ELEMENTS 17
int M;
int A[ELEMENTS];
struct WorkletInfo {
int *data_base;
int count;
};
void *worklet(void *t)
{
int i;
struct WorkletInfo *wi = t; /* note: no cast here */
if(!wi)
return 0;
for(i=0; i < wi->count; i++)
wi->data_base[i] *= M;
return wi;
}
#define N_CPUS 4
#define NUM_THREADS (N_CPUS+1)
int main(int argc, char *argv[])
{
int t, ec;
pthread_t th[NUM_THREADS];
int remaining_elements;
int const elements_per_worklet = ELEMENTS/NUM_THREADS;
srand(time(0));
M=rand();
/* you must initialize the data a thread will access before starting the thread */
for(t = 0; t < ELEMENTS; t++)
A[t]=t+1; /* 0 * x = 0, so give it some nonzero value */
remaining_elements = ELEMENTS - (elements_per_worklet*NUM_THREADS);
ec = 0;
for(t = 0; t < NUM_THREADS; t++)
{
struct WorkletInfo *wi = malloc(sizeof(*wi));
wi->data_base = &A[ec];
wi->count = elements_per_worklet;
if(t<remaining_elements) {
wi->count++;
}
ec += wi->count;
pthread_create(&th[t], NULL, worklet, wi);
}
ec = 0;
for(t = 0; t < NUM_THREADS; t++)
{
int i;
struct WorkletInfo *wi;
void *retval;
pthread_join(th[t], &retval);
if(!retval)
continue;
wi = retval;
for(i = 0; i < wi->count; i++, ec++)
printf("worklet %d, worklet element %d => total element %d: %d\n",
t, i, ec,
wi->data_base[i]);
free(wi);
}
printf("Thread main\n");
return 0;
}
这个程序的输出是这样的:
worklet 0, worklet element 0 => total element 0: 300787748
worklet 0, worklet element 1 => total element 1: 601575496
worklet 0, worklet element 2 => total element 2: 902363244
worklet 1, worklet element 0 => total element 3: 1203150992
worklet 1, worklet element 1 => total element 4: 1503938740
worklet 1, worklet element 2 => total element 5: 1804726488
worklet 1, worklet element 3 => total element 6: 2105514236
worklet 2, worklet element 0 => total element 7: -1888665312
worklet 2, worklet element 1 => total element 8: -1587877564
worklet 2, worklet element 2 => total element 9: -1287089816
worklet 3, worklet element 0 => total element 10: -986302068
worklet 3, worklet element 1 => total element 11: -685514320
worklet 3, worklet element 2 => total element 12: -384726572
worklet 3, worklet element 3 => total element 13: -83938824
worklet 4, worklet element 0 => total element 14: 216848924
worklet 4, worklet element 1 => total element 15: 517636672
worklet 4, worklet element 2 => total element 16: 818424420
Thread main exit