pthread_join 挂起相应的随机全局变量值

pthread_join hangs accordingly to random global variable value

我使用 pthreads 构建了这段代码。目标是构建一个数组 X[N][D] 并为其分配随机值。您可以将此数组的元素读取为某些点的系数。

在下一步中,我试图计算一个数组 distances[N],它包含最后一个元素(第 N 个)与其他元素之间的所有距离。使用 pthreads.

执行距离计算
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>

#define N 10
#define D 2         //works for any d
#define NUM_THREADS 8


//double *distances;
//int global_index = 0;
pthread_mutex_t lock;
double *X;

typedef struct
{
    //int thread_id;
    double *distances;
    int *global_index ;
    pthread_mutex_t lock;
    double *X;

}parms;

void *threadDistance(void *arg)
{
    parms *data = (parms *) arg;
    double *distances = data->distances;
    double *X = data->X;
    int *global_idx = data -> global_index;

    int idx,j;
    //long id = (long)arg;
    pthread_mutex_lock(&lock);

    while(*global_idx<N)
    {
        //printf("Thread #%ld , is calculating\n", id);
        idx = *(global_idx);
        (*global_idx)++;
        pthread_mutex_unlock(&lock);
        for(j=0 ; j<D; j++)
        {
            distances[idx] = pow(X[(j+1)*N-1]-X[j*N+idx], 2);
            //printf("dis[%d]= ", dis);
            //printf("%f\n",distances[idx]);
        }
        //printf("global : %d\n", *global_idx);
    }


    pthread_exit(NULL);


}

void calcDistance(double * X, int n, int d)
{
    int i;
    int temp=0;
    pthread_t threads[NUM_THREADS];
    double *distances = malloc(n * sizeof(double));

    parms arg;
    arg.X = X;
    arg.distances = distances;
    arg.global_index = &temp;

    for (i=0 ; i<NUM_THREADS ; i++)
    {
        pthread_create(&threads[i], NULL, threadDistance, (void *) &arg);
    }

    for(i = 0 ; i<NUM_THREADS; i++)
    {
        pthread_join(threads[i], NULL);
    }

    /*----print dstances[] array-------*/
    printf("--------\n");
    for(int i = 0; i<N; i++)
    {
        printf("%f\n", distances[i]);
    }
    /*------------*/
    free(distances);
}

int main()
{

    srand(time(NULL));

    //allocate the proper space for X
    X = malloc(D*N*(sizeof(double)));

    //fill X with numbers in space (0,1)
    for(int i = 0 ; i<N ; i++)
    {
        for(int j=0; j<D; j++)
        {
            X[i+j*N] = (double) (rand()  / (RAND_MAX + 2.0));
        }

    }

    calcDistance(X, N, D);


    return 0;
}

问题在于代码仅在N=100000时才完全执行。如果 N!=100000 代码挂起,我发现问题的根源是 pthread_join() 函数。首先,我无法理解为什么挂起取决于 N.

的值

其次,我已经尝试 printf()ing global_index 的值(如您所见,它在这个特定的代码示例中被注释掉了)。只要我取消注释 printf("global : %d\n", *global_idx); 命令,程序就会停止挂起,无论 N 的值如何。

我觉得这很疯狂,因为悬挂和不悬挂之间的区别是如此无关紧要。

关于:

pthread_mutex_lock(&lock); 
while(*global_idx<N) 
{  
    // ... 
    pthread_mutex_unlock(&lock); 

结果是在循环的第一次迭代之后,互斥锁总是解锁的。建议将对 pthread_mutex_lock() 的调用移至循环顶部。

在做了上面的修正之后,我又把N设置为10000。然后重新编译等等。结果是seg fault event,所以mutex的错误处理不是唯一的问题.

关于:

* First of all I cannot understand why the hang depends on the value of N.*

看来程序实际上是因段错误事件而崩溃,而不是挂起