具有posix线程的数组的内部产品空间

时间:2018-05-27 17:01:50

标签: c linux pthreads

我想从用户那里读取表A和B作为输入,并从它们创建一个内部产品空间(a1b1 + a2b2 + ...... + anbn)并将其保存在local_sum中,然后将其共享到total_sum变量。我正在做波纹管代码,但是存在段故障。出于某种原因,表格A& B无法传递给MUL功能。任何帮助都会很棒,谢谢!

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

#define N 2

int p;
int A[N],B[N];
int local_sum;

void *mul(void *arg)
{
    int lines, start, end, i, j;
    int id = *(int*)arg;
    lines = N / p;
    start = id * lines;
    end = start + lines;

    for (i = start; i < end; i++)
        local_sum = A[i] * B[i] + local_sum;

    return NULL;
}

int main (int argc, char *argv[])
{
    int i;
    pthread_t *tid;

    if (argc != 2)
    {
        printf("Provide number of threads.\n");
        exit(1);
    }

    p = atoi(argv[1]);

    tid = (pthread_t *)malloc(p * sizeof(pthread_t));
    if (tid == NULL)
    {
        printf("Could not allocate memory.\n");
        exit(1);
    }

    printf("Give Table A\n");

    for (int i = 0; i < N; i++)
    {
        scanf("%d", &A[i]);
    }

    printf("Give Table B\n");

    for (int i = 0; i < N; i++)
    {
        scanf("%d", &B[i]);
    }

    for (i = 0; i < p; i++)
    {
        int *a;
        a = malloc(sizeof(int));
        *a = 0;
        pthread_create(&tid[i], NULL, mul, a);
    }

    for (i = 0; i < p; i++)
        pthread_join(tid[i], NULL);

    printf("%d", local_sum);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

if (tid=NULL)

- &GT;

  if (tid==NULL)

for (i=start;i<end;i++)

我想我们需要

for (i=0;i<end-start;i++)

答案 1 :(得分:0)

让我们看看:

您希望拥有p个主题,处理向量AB

您必须知道线程共享相同的内存,并且可能随时中断。

您有p个帖子,都试图写入一个共享变量local_sum。这会导致不可预测的结果,因为一个线程会覆盖另一个线程之前写过的值。

您可以通过使用互斥锁等确保将单个线程独占访问此变量来绕过此问题,或者每个线程可以有一个变量,每个线程产生一个中间结果,并且在连接所有线程后,崩溃所有中间结果都进入最后一个。

要做到这一点,你的main应该看起来像(假设你的编译器支持最新的C标准):

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

#define N 2
/* these are variables shared amongst all threads */  
int p;
int A[N], B[N];

/* array with one slot per thread to receive the partial result of each thread */
int* partial_sum;

/* prototype of thread function, just to be independent of the place mul will be placed in the source file... */
void *mul(void *arg);

int main (int argc, char** argv) 
{
    pthread_t* tid;
    p = atoi(argv[1]);
    const size_t n_by_p = N/p; 
    if(n_by_p * p  != N)
    {
          fprintf(stderr, "Number of threads must be an integral factor of N\n");
          exit(EXIT_FAILURE) ;
    } 

    tid = calloc(p, sizeof(pthread_t));
    partial_sum = calloc(p, sizeof(int)) ;

    printf("Give Table A\n");
    for(size_t i = 0; i < N; ++i) 
    {
         scanf("%d",&A[i]);
    }
    printf("Give Table B\n");
    for(size_t i = 0; i < N; ++i)
    {
         scanf("%d",&B[i]);
    }   

    for (size_t i =0; i < p; ++i) 
    {
        /* clumsy way to pass a thread it's slot number, but works as a starter... */
        int *a;
        a = malloc(sizeof(int));
        *a = i;
        pthread_create(&tid[i], 0, mul, a);
    }

    for (size_t i = 0; i < p; ++i)
    {
        pthread_join(tid[i], 0);
    } 
    free(tid);
    tid = 0;

    int total_sum = 0;

    for (size_t i = 0; i < p; ++i) 
    {
        total_sum += partial_sum[i] ;
    } 

    free(partial_sum);
    partial_sum = 0;

    printf("%d",total_sum);
    return EXIT_SUCCESS;
}

您的线程方法mul现在应该只写入其特定的partial_sum广告位:

void *mul(void *arg)
{
    int slot_num = *(int*)arg;
    free(arg);
    arg = 0;

    const size_t lines = N/p;
    const size_t start  = slot_num * lines;
    const size_t end = start + lines;

    partial_sum[slot_num] = 0;
    for(size_t i = start; i < end; ++i) 
    {
            partial_sum[slot_num] += A[i]*B[i];
    } 
    return 0;
}

注意:只有当Np的某个整数倍时,此代码才能顺利运行。 如果由于N/p中的截断而未满足此条件,则不会处理向量的所有元素。 然而,修复这些案件并不是恕我直言的这个问题的核心。

如果此代码成为某些操作设置的一部分,我应该避免各种错误检查...