c - 将 pthreads 用于点积时出现段错误

标签 c segmentation-fault pthreads dot-product faults

我一直在尝试为 pthreads 制作一个点积程序,但遇到了一些困难。当我尝试运行该程序时出现段错误。我正在使用 c 对其进行编码。

我让程序最初使用这段代码工作:

a = (double*) malloc (THREAD_COUNT* SIZE *  sizeof(double));
b = (double*) malloc (THREAD_COUNT* SIZE *  sizeof(double));

for (i=0; i<SIZE*THREAD_COUNT; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);


gettimeofday (&time_start, NULL);

for(i=0;i<THREAD_COUNT;i++)
  {

   pthread_create(&callThd[i], &attr, dotprod, (void *)i); 
   }

pthread_attr_destroy(&attr);

for(i=0;i<THREAD_COUNT;i++) {
  pthread_join(callThd[i], &status);
  }

然后我更改了内存分配,因为我不想通过增加线程数来增加总和。

这是修改后的代码:

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);


gettimeofday (&time_start, NULL);

for(i=0;i<THREAD_COUNT;i++)
  {

   pthread_create(&callThd[i], &attr, dotprod, (void *)i);
   }

pthread_attr_destroy(&attr);

for(i=0;i<THREAD_COUNT;i++) {
  pthread_join(callThd[i], &status);
  }

这是我的全部代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h> //gettimeofday()
typedef struct
 {
   double      *a;
   double      *b;
   double     sum;
   int     size;
 } DOTPROD;

/* Define globally accessible variables and a mutex */

typedef struct
{

int secs;
int microsecs;


}TIME;

//TIME * time_diff(struct timeval *, struct timeval *);


#define THREAD_COUNT 20
#define SIZE 100000
   DOTPROD dot;
   pthread_t callThd[THREAD_COUNT];
   pthread_mutex_t mutexsum;






void *dotprod(void *arg)
{

/* Define and use local variables for convenience */

   int i, start, end, reg_size ;
   long offset;
   double partsum, *x, *y;
   offset = (long)arg;

   reg_size = dot.size;
   start = offset*reg_size;
   end   = start + reg_size;
   x = dot.a;
   y= dot.b;     /*                                        
 * Perform the dot product and assign result
 * to the appropriate variable in the structure. 
 * */
   partsum = 0;
   for (i=start; i<end ; i++)
    {
      partsum += (x[i] * y[i]);
    }

/*
 * Lock a mutex prior to updating the value in the shared
 * structure, and unlock it upon updating.
 * */
   pthread_mutex_lock (&mutexsum);
   dot.sum += partsum;
   pthread_mutex_unlock (&mutexsum);

   pthread_exit((void*) 0);
}



int main (int argc, char *argv[])
{
long i;
double *a, *b;
void *status;
struct timeval time_start, time_end;

TIME*diff;
pthread_attr_t attr;
/* Assign storage and initialize values */

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
                                                   55,16         58%
 * Perform the dot product and assign result
 * to the appropriate variable in the structure. 
 * */
   partsum = 0;
   for (i=start; i<end ; i++)
    {
      partsum += (x[i] * y[i]);
    }

/*
 * Lock a mutex prior to updating the value in the shared
 * structure, and unlock it upon updating.
 * */
   pthread_mutex_lock (&mutexsum);
   dot.sum += partsum;
   pthread_mutex_unlock (&mutexsum);

   pthread_exit((void*) 0);
}



int main (int argc, char *argv[])
{
long i;
double *a, *b;
void *status;
struct timeval time_start, time_end;

TIME*diff;
pthread_attr_t attr;
/* Assign storage and initialize values */

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
                                                   55,16         58%
 * Perform the dot product and assign result
 * to the appropriate variable in the structure. 
 * */
   partsum = 0;
   for (i=start; i<end ; i++)
    {
      partsum += (x[i] * y[i]);
    }

/*
 * Lock a mutex prior to updating the value in the shared
 * structure, and unlock it upon updating.
 * */
   pthread_mutex_lock (&mutexsum);
   dot.sum += partsum;
   pthread_mutex_unlock (&mutexsum);

   pthread_exit((void*) 0);
}



int main (int argc, char *argv[])
{
long i;
double *a, *b;
void *status;
struct timeval time_start, time_end;

TIME*diff;
pthread_attr_t attr;
/* Assign storage and initialize values */

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
                                                   55,16         58%
 * Perform the dot product and assign result
 * to the appropriate variable in the structure. 
 * */
   partsum = 0;
   for (i=start; i<end ; i++)
    {
      partsum += (x[i] * y[i]);
    }

/*
 * Lock a mutex prior to updating the value in the shared
 * structure, and unlock it upon updating.
 * */
   pthread_mutex_lock (&mutexsum);
   dot.sum += partsum;
   pthread_mutex_unlock (&mutexsum);

   pthread_exit((void*) 0);
}



int main (int argc, char *argv[])
{
long i;
double *a, *b;
void *status;
struct timeval time_start, time_end;

TIME*diff;
pthread_attr_t attr;
/* Assign storage and initialize values */

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
                                                   * Perform the dot product and assign result
 * to the appropriate variable in the structure. 
 * */
   partsum = 0;
   for (i=start; i<end ; i++)
    {
      partsum += (x[i] * y[i]);
    }

/*
 * Lock a mutex prior to updating the value in the shared
 * structure, and unlock it upon updating.
 * */
   pthread_mutex_lock (&mutexsum);
   dot.sum += partsum;
   pthread_mutex_unlock (&mutexsum);

   pthread_exit((void*) 0);
}



int main (int argc, char *argv[])
{
long i;
double *a, *b;
void *status;
struct timeval time_start, time_end;

TIME*diff;
pthread_attr_t attr;
/* Assign storage and initialize values */

a = (double*) malloc ( SIZE *  sizeof(double));
b = (double*) malloc (SIZE *  sizeof(double));

for (i=0; i<SIZE; i++) {
  a[i]=1;
  b[i]=a[i];
  }

dot.size = SIZE;
dot.a = a;
dot.b = b;
dot.sum=0;

pthread_mutex_init(&mutexsum, NULL);

/* Create threads to perform the dotproduct  */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

gettimeofday (&time_start, NULL);

for(i=0;i<THREAD_COUNT;i++)
  {

   pthread_create(&callThd[i], &attr, dotprod, (void *)i);
   }

pthread_attr_destroy(&attr);

for(i=0;i<THREAD_COUNT;i++) {
  pthread_join(callThd[i], &status);
  }
/* After joining, print out the results and cleanup */



gettimeofday (&time_end, NULL);


long long elasped = (time_end.tv_sec - time_start.tv_sec)*1000000LL + time_end.tv_usec - time_start.tv_usec;

printf ("time diff in microseconds = %6d \n",elasped);

printf ("Sum =  %f \n", dot.sum);
//diff = time_diff(&time_start, &time_end);

//printf("Time = %d. \%5d.%6d secs. \n", diff->secs, diff -> microsecs);
free (a);
free (b);
pthread_mutex_destroy(&mutexsum);
pthread_exit(NULL);

}

最佳答案

在初始代码中,dot.sizeSIZE 是一回事, vector 大小是SIZE * THREAD_COUNT。因此,如果您有 4 个线程并且每个线程进行 5 次乘法运算,则 vector 大小为 20。

在新代码中,SIZE 现在是 vector 大小,您正试图在 THREAD_COUNT 个线程之间分配工作。因此 dot.size 需要为 SIZE/THREAD_COUNT。因此,如果 SIZE 为 20 而 THREAD_COUNT 为 4,则 dot.size 需要为 20/4 = 5。

关于c - 将 pthreads 用于点积时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29403557/

相关文章:

c - 如何等待 pthread 条件变量或信号?

c - 编写一个 C 程序来判断给定的字符串是否是 Lucky

c++ - 映射共享库部分 : libhmmm. 时出错,因此:成功

CUDA BFS 巨图(seg.fault)

c - 访问越界内存后,段错误不会立即出现

Android 录制音频时出现 SIGSEGV 错误

c++ - pthread_cond_wait() 能否始终赢得锁定互斥体的竞争?

c - 处理 pthread 以干净退出

c - Valgrind 发现内存泄漏,但我无法理解

c - 将 3d 数组发送到 CUDA 内核