Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在for循环中一次又一次地创建和连接线程(C)_C_Loops_For Loop_Pthreads - Fatal编程技术网

在for循环中一次又一次地创建和连接线程(C)

在for循环中一次又一次地创建和连接线程(C),c,loops,for-loop,pthreads,C,Loops,For Loop,Pthreads,我写了一个程序,在C语言中执行高斯消去,并返回矩阵的L2范数。该程序的调用类似于/exec n k,其中n是nxn矩阵的大小,k是将用于执行该程序的线程数(最多4个)。我像./gauss304那样运行程序,它会出错 在使用GDB之后,我发现有比预期多得多的线程退出,我认为因为我的线程是在for循环中生成的,它们被一次又一次地连接和创建,这导致了seg故障。有人能给我指一下正确的方向吗 #include <stdlib.h> #include <stdio.h> #incl

我写了一个程序,在C语言中执行高斯消去,并返回矩阵的L2范数。该程序的调用类似于
/exec n k
,其中n是nxn矩阵的大小,k是将用于执行该程序的线程数(最多4个)。我像./gauss304那样运行程序,它会出错

在使用GDB之后,我发现有比预期多得多的线程退出,我认为因为我的线程是在for循环中生成的,它们被一次又一次地连接和创建,这导致了seg故障。有人能给我指一下正确的方向吗

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <omp.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>

//globals
double **a, *vect, *bvect, scalar, ratio, sum, delta, *temp;
int i,j,k,ptr, z;
int y,z;
int bvectcount = 0;
int threadcount;
pthread_t workerThreads[4];
typedef struct threader {
    int counter;
    int matrixl;
} threader;
struct timeval start, end;
    void *retval;

int checkargs(int argc, char* argv[]);
// a is matrix, b is vector, x is the solution vector, and n is the size 
double L2(double **a, double *bvect, double *vect, int matrixSize) {
    double sum;
    double res[matrixSize];
    int i, j;
    for (i=0; i < matrixSize; i++) {
        sum = (double) 0;
        for (j=0; j < matrixSize; j++) {
            sum += a[i][j] * vect[j];
        }
        res[i] = sum;
    }
    for (i=0; i < matrixSize; i++) {
        res[i] -= vect[i];
    }
    double squaresum = (double) 0;
    for (i=0; i < matrixSize; i++) {
        squaresum += res[i] * res[i];
    }
    return sqrt(squaresum);
}
int checkargs(int argc, char* argv[]){
    if(argc != 3){
        fprintf(stderr, "Error: Usage is size threadNum\n" );
        exit(1);
    }
}

void *parallelstuff(void *args){
    threader temp = *((threader *)args);
    int i, matrixSize;
    i = temp.counter;
    matrixSize = temp.matrixl;
    double temp2;
    for(j = i + 1; j<matrixSize; j++){
        temp2 = a[j][i]/a[i][i];
        for(z = 0; z<matrixSize + 1; z++){
            a[j][z] = a[j][z] - temp2 * a[i][z];
        }
    }
}
int main(int argc, char* argv[]){
    //check for args
    checkargs(argc, argv);
    int matrixSize = atoi(argv[1]);
    int threadNum = atoi(argv[2]);
    //memory allocation
     a = (double**)malloc(matrixSize*sizeof(double*));
    for(i = 0; i < matrixSize ; i++)
        a[i] = (double*)malloc(matrixSize*sizeof(double) * matrixSize);
    vect = (double*)malloc(matrixSize*sizeof(double));
    bvect = (double*)malloc(matrixSize*sizeof(double));
    temp = (double*)malloc(matrixSize*sizeof(double));
    for(i = 0; i < matrixSize; ++i){
        for(j = 0; j < matrixSize + 1; ++j){
            a[i][j] = drand48(); 
        }
    }
    j = 0;
    j += matrixSize;
    for(i = 0; i < matrixSize; ++i){
        bvect[i] = a[i][j];
    }
//generation of scalar matrix (diagonal vector)
    gettimeofday(&start, NULL);
    for(i=0; i<matrixSize; i++){
        scalar = a[i][i];
    //initialization of p to travel throughout matrix
        ptr = i;
    //find largest number in column and row number of it
        for(k = i+1; k < matrixSize; k++){
        if(fabs(scalar) < fabs(a[k][i])){
            //k is row of scalar, while
           scalar = a[k][i];
           ptr = k;
        }
    }
    //swaping the elements of diagonal row and row containing largest no
    for(j = 0; j <= matrixSize; j++)
    {
        temp[0] = a[i][j];
        a[i][j]= a[ptr][j];
        a[ptr][j] = temp[0];
    }
    ratio = a[i][i];
    for(k = 0; k < matrixSize + 1; k++){
        a[i][k] = a[i][k] / ratio;
    }   
    threader stuff;
    stuff.counter = i;
    stuff.matrixl = matrixSize;
    //MAKE EACH THREAD DO SOMETHING DIFF
    //
    // parallelstuff(int i, int matrixSize, double **a){
    for(threadcount = 0; threadcount < threadNum; threadcount++){
        if(pthread_create (&workerThreads[threadcount], NULL, parallelstuff, (void *) &stuff ) != 0){
            fprintf(stderr, "Error: consumer create problem\n");
            exit(1);
            }
        }
    while(threadcount != 0){
        if(pthread_join (workerThreads[threadcount-1], &retval ) != 0){
        fprintf(stderr, "Error: consumer create problem\n");
        exit(1);
        }
        threadcount--;
    }


    //create matrix of n size 
    //backward substitution method
    for(i=matrixSize-1; i >=0; i--){
        for(k = i; k > 0; k--){
            a[k-1][matrixSize] -= a[k-1][i] * a[i][matrixSize];
            a[k-1][i] -= a[k-1][i] * a[i][i];
        }  
    }
    for(i = 0; i < matrixSize; ++i){
        vect[i] = a[i][matrixSize];
        }       
    double l2Norm;
    l2Norm = L2(a, bvect, vect, matrixSize);
    printf("THIS IS L2 NORM: %f\n", l2Norm);
    gettimeofday(&end, NULL);
    delta = ((end.tv_sec  - start.tv_sec) * 1000000u + 
         end.tv_usec - start.tv_usec) / 1.e6;
    printf("end time: %f\n", delta);
}
        }
编辑:我在GDB中发现了一些有趣的东西,它告诉了我们很多关于这个问题的信息。这将永远循环,然后最终分段故障。有人能帮我理解这是什么吗

这一行

for(j = 0; j < matrixSize + 1; ++j){
    a[i][j] = drand48(); 
}
(j=0;j{ a[i][j]=drand48(); } 错误,并导致在矩阵的每行末尾进行越界访问


您可以查看
valgrind
或类似的工具,帮助您检测此类越界访问。

以下代码包含有关更改的注释

Note: for clarity and maintainability, only one variable per line
Note: for clarity, all braces are included
Note: added brace at end of main() function that should be elsewhere in the function
Note: there are still two compile problems, as noted in the code:
1) function drand48() not defined
2) parameter bvect in function l2 not used.

Please fix all the remaining problems in the code and re-post

#include <stdlib.h>
#include <stdio.h>
#include <math.h> // sqrt()
#include <omp.h>
#include <time.h> // time() gettimeofday()
#include <sys/time.h>
#include <pthread.h>
#include <string.h> // memcpy()

struct threader
{
    int counter;
    int matrixl;
};

//globals
double **a;
double *vect;
double *bvect;
double scalar;
double ratio;
double sum;
double delta;
double *temp;

int i;
int j;
int k;
int ptr;
int z;
int y;
//int z; <-- second declaration of same variable

int bvectcount = 0; // unused variable

int threadcount;
pthread_t workerThreads[4];

struct timeval start; // beginn execution time
struct timeval end;   // end    execution time

void *retval;

// prototypes
// a is matrix, b is vector, x is the solution vector, and n is the size
double L2(double **a, double *bvect, double *vect, int matrixSize);

// thread function
void *parallelstuff(void *args);

// check command line argumen counts
int checkargs(int argc, char* argv[]);







int main(int argc, char* argv[])
{
    //check for args
    checkargs(argc, argv);

    int matrixSize = atoi(argv[1]);
    if( 0 >= matrixSize )
    {
        // handle error; exit(1);
    }

    int threadNum = atoi(argv[2]);
    if( (0 >= threadNum) || (4 < threadNum) )
    {
        // handle error; exit(1);
    }

    //memory allocation
    if( NULL == (a = malloc(matrixSize*sizeof(double*)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    for(i = 0; i < matrixSize ; i++)
    {
        if( NULL == (a[i] = malloc(matrixSize*sizeof(double) * matrixSize) ) )
        {
            //perror(); call cleanup; exit(1);
        }
    }


    if( NULL == (vect  = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    if( NULL == (bvect = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    if( NULL == (temp  = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    for(i = 0; i < matrixSize; ++i)
    {
        for(j = 0; j < matrixSize + 1; ++j)
        {
            a[i][j] = drand48(); // where is this function defined?
        }
    }


    j = matrixSize;

    for(i = 0; i < matrixSize; ++i)
    {
        bvect[i] = a[i][j];
    }

    //generation of scalar matrix (diagonal vector)
    gettimeofday(&start, NULL); // time how long this takes to execute

    for(i=0; i<matrixSize; i++)
    {
        scalar = a[i][i];

        //initialization of p to travel throughout matrix
        ptr = i;

        //find largest number in column and row number of it
        for(k = i+1; k < matrixSize; k++)
        {
            if(fabs(scalar) < fabs(a[k][i]))
            {
                //k is row of scalar, while
                scalar = a[k][i];
                ptr = k;
            }
        }

        //swaping the elements of diagonal row and row containing largest no
        for(j = 0; j <= matrixSize; j++)
        {
            temp[0] = a[i][j];
            a[i][j]= a[ptr][j];
            a[ptr][j] = temp[0];
        }

        ratio = a[i][i];

        for(k = 0; k < matrixSize + 1; k++)
        {
            a[i][k] = a[i][k] / ratio;
        }

        struct threader stuff;
        stuff.counter = i;
        stuff.matrixl = matrixSize;

        // parallelstuff(int i, int matrixSize, double **a){

        for(threadcount = 0; threadcount < threadNum; threadcount++)
        {
            if( pthread_create( &workerThreads[threadcount], NULL, parallelstuff, (void *) &stuff ) )
            {
                fprintf(stderr, "Error: consumer create problem\n");
                exit(1);
            }
        }


        while(threadcount != 0)
        {
            if(pthread_join (workerThreads[threadcount-1], &retval ) != 0)
            {
                fprintf(stderr, "Error: consumer create problem\n");
                exit(1);
            }
            threadcount--;
        }

        //create matrix of n size
        //backward substitution method
        for(i=matrixSize-1; i >=0; i--)
        {
            for(k = i; k > 0; k--)
            {
                a[k-1][matrixSize] -= a[k-1][i] * a[i][matrixSize];
                a[k-1][i] -= a[k-1][i] * a[i][i];
            }
        }

        for(i = 0; i < matrixSize; ++i)
        {
            vect[i] = a[i][matrixSize];
        }

        double l2Norm;
        l2Norm = L2(a, bvect, vect, matrixSize);
        printf("THIS IS L2 NORM: %f\n", l2Norm);
        gettimeofday(&end, NULL);
        delta =
            ((end.tv_sec  - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6;
        printf("end time: %f\n", delta);

        return(0);
    } // supply missing closing brace, just for testing, where should this actually be placed?
    } // end function: main


double L2(double **a, double *bvect, double *vect, int matrixSize) // unused param: bvect
{
    double sum;
    double res[matrixSize];
    int i;
    int j;

    for (i=0; i < matrixSize; i++)
    {
        sum = 0.0;

        for (j=0; j < matrixSize; j++)
        {
            sum += a[i][j] * vect[j];
        }
        res[i] = sum;
    }

    for (i=0; i < matrixSize; i++)
    {
        res[i] -= vect[i];
    }

    double squaresum = 0.0;

    for (i=0; i < matrixSize; i++)
    {
        squaresum += res[i] * res[i];
    }

    return sqrt(squaresum);
} // end function: L2


// this function changes global array 'a[]'
// to avoid race conditions, a mutex should be used to lock the resource (a[])
//  while it is being modified
void *parallelstuff(void *args)
{
    struct threader temp;    // this shadows global 'temp' variable
    memcpy ( &temp, (struct threader *)args, sizeof(struct threader) );

    int j;
    int z;

    int i = temp.counter;
    int matrixSize = temp.matrixl;

    double temp2 = 0.0;

    for(j = i + 1; j<matrixSize; j++)
    {
        temp2 = a[j][i] / a[i][i];
        for(z = 0; z<matrixSize + 1; z++) // this will access memory beyond the bounds of 2d matrix a[]
        {
            a[j][z] = a[j][z] - temp2 * a[i][z];
        }
    }

    pthread_exit( NULL );
} // end function: parallelstuff


int checkargs(int argc, char* argv[])
{
    if(argc != 3)
    {
        fprintf(stderr, "Error: Usage: %s size threadNum\n", argv[0] );
        exit(1);
    }

    return( 0 );
} // end function: checkargs
注意:为了清晰和可维护性,每行只有一个变量
注:为清晰起见,包括所有支架
注意:在main()函数末尾添加了大括号,该大括号应位于函数的其他位置
注意:如代码中所述,仍然存在两个编译问题:
1) 未定义函数drand48()
2) 函数l2中的参数bvect未使用。
请修复代码中的所有剩余问题并重新发布
#包括
#包括
#include//sqrt()
#包括
#包括//time()gettimeofday()
#包括
#包括
#include//memcpy()
结构螺纹机
{
整数计数器;
int矩阵;
};
//全球的
双**a;
双*向量;
双*bvect;
双标量;
双倍比率;
双和;
双三角洲;
双*温度;
int i;
int j;
int k;
int-ptr;
intz;
int-y;
//int z;=矩阵大小)
{
//处理错误;退出(1);
}
int threadNum=atoi(argv[2]);
如果((0>=threadNum)| |(4对于(j=i+1;j2风格?我有一个checkargs的原型,以前我把main放在它上面,但是我把checkargs移到main上面,只是忘了把原型去掉。oops,我错过了
首先,去掉程序中的所有类型转换。它们完全没有用,可能只是隐藏bug。然后不要把指针数组用作假矩阵。C有更容易处理的2D矩阵构建。类似于
double(*A)[n]=malloc(sizeof(double[n][n]))
这项工作很容易完成。你的问题很可能只是你复杂的分配方案。另外,请正确缩进你的代码,这是一个阅读困难的问题。我已经缩进了不合适的行!这实际上是高斯消去法的一个增广矩阵,这是有意的,我担心是有意的还是无意的,你不分配他为它留出了空间。我已经修复了它。但是,我在OpenMP版本的程序中使用了几乎相同的代码,并且它运行得完美无缺。我知道我的代码是wro
Note: for clarity and maintainability, only one variable per line
Note: for clarity, all braces are included
Note: added brace at end of main() function that should be elsewhere in the function
Note: there are still two compile problems, as noted in the code:
1) function drand48() not defined
2) parameter bvect in function l2 not used.

Please fix all the remaining problems in the code and re-post

#include <stdlib.h>
#include <stdio.h>
#include <math.h> // sqrt()
#include <omp.h>
#include <time.h> // time() gettimeofday()
#include <sys/time.h>
#include <pthread.h>
#include <string.h> // memcpy()

struct threader
{
    int counter;
    int matrixl;
};

//globals
double **a;
double *vect;
double *bvect;
double scalar;
double ratio;
double sum;
double delta;
double *temp;

int i;
int j;
int k;
int ptr;
int z;
int y;
//int z; <-- second declaration of same variable

int bvectcount = 0; // unused variable

int threadcount;
pthread_t workerThreads[4];

struct timeval start; // beginn execution time
struct timeval end;   // end    execution time

void *retval;

// prototypes
// a is matrix, b is vector, x is the solution vector, and n is the size
double L2(double **a, double *bvect, double *vect, int matrixSize);

// thread function
void *parallelstuff(void *args);

// check command line argumen counts
int checkargs(int argc, char* argv[]);







int main(int argc, char* argv[])
{
    //check for args
    checkargs(argc, argv);

    int matrixSize = atoi(argv[1]);
    if( 0 >= matrixSize )
    {
        // handle error; exit(1);
    }

    int threadNum = atoi(argv[2]);
    if( (0 >= threadNum) || (4 < threadNum) )
    {
        // handle error; exit(1);
    }

    //memory allocation
    if( NULL == (a = malloc(matrixSize*sizeof(double*)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    for(i = 0; i < matrixSize ; i++)
    {
        if( NULL == (a[i] = malloc(matrixSize*sizeof(double) * matrixSize) ) )
        {
            //perror(); call cleanup; exit(1);
        }
    }


    if( NULL == (vect  = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    if( NULL == (bvect = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    if( NULL == (temp  = malloc(matrixSize*sizeof(double)) ) )
    {
        // perror(); call cleanup; exit(1);
    }

    for(i = 0; i < matrixSize; ++i)
    {
        for(j = 0; j < matrixSize + 1; ++j)
        {
            a[i][j] = drand48(); // where is this function defined?
        }
    }


    j = matrixSize;

    for(i = 0; i < matrixSize; ++i)
    {
        bvect[i] = a[i][j];
    }

    //generation of scalar matrix (diagonal vector)
    gettimeofday(&start, NULL); // time how long this takes to execute

    for(i=0; i<matrixSize; i++)
    {
        scalar = a[i][i];

        //initialization of p to travel throughout matrix
        ptr = i;

        //find largest number in column and row number of it
        for(k = i+1; k < matrixSize; k++)
        {
            if(fabs(scalar) < fabs(a[k][i]))
            {
                //k is row of scalar, while
                scalar = a[k][i];
                ptr = k;
            }
        }

        //swaping the elements of diagonal row and row containing largest no
        for(j = 0; j <= matrixSize; j++)
        {
            temp[0] = a[i][j];
            a[i][j]= a[ptr][j];
            a[ptr][j] = temp[0];
        }

        ratio = a[i][i];

        for(k = 0; k < matrixSize + 1; k++)
        {
            a[i][k] = a[i][k] / ratio;
        }

        struct threader stuff;
        stuff.counter = i;
        stuff.matrixl = matrixSize;

        // parallelstuff(int i, int matrixSize, double **a){

        for(threadcount = 0; threadcount < threadNum; threadcount++)
        {
            if( pthread_create( &workerThreads[threadcount], NULL, parallelstuff, (void *) &stuff ) )
            {
                fprintf(stderr, "Error: consumer create problem\n");
                exit(1);
            }
        }


        while(threadcount != 0)
        {
            if(pthread_join (workerThreads[threadcount-1], &retval ) != 0)
            {
                fprintf(stderr, "Error: consumer create problem\n");
                exit(1);
            }
            threadcount--;
        }

        //create matrix of n size
        //backward substitution method
        for(i=matrixSize-1; i >=0; i--)
        {
            for(k = i; k > 0; k--)
            {
                a[k-1][matrixSize] -= a[k-1][i] * a[i][matrixSize];
                a[k-1][i] -= a[k-1][i] * a[i][i];
            }
        }

        for(i = 0; i < matrixSize; ++i)
        {
            vect[i] = a[i][matrixSize];
        }

        double l2Norm;
        l2Norm = L2(a, bvect, vect, matrixSize);
        printf("THIS IS L2 NORM: %f\n", l2Norm);
        gettimeofday(&end, NULL);
        delta =
            ((end.tv_sec  - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6;
        printf("end time: %f\n", delta);

        return(0);
    } // supply missing closing brace, just for testing, where should this actually be placed?
    } // end function: main


double L2(double **a, double *bvect, double *vect, int matrixSize) // unused param: bvect
{
    double sum;
    double res[matrixSize];
    int i;
    int j;

    for (i=0; i < matrixSize; i++)
    {
        sum = 0.0;

        for (j=0; j < matrixSize; j++)
        {
            sum += a[i][j] * vect[j];
        }
        res[i] = sum;
    }

    for (i=0; i < matrixSize; i++)
    {
        res[i] -= vect[i];
    }

    double squaresum = 0.0;

    for (i=0; i < matrixSize; i++)
    {
        squaresum += res[i] * res[i];
    }

    return sqrt(squaresum);
} // end function: L2


// this function changes global array 'a[]'
// to avoid race conditions, a mutex should be used to lock the resource (a[])
//  while it is being modified
void *parallelstuff(void *args)
{
    struct threader temp;    // this shadows global 'temp' variable
    memcpy ( &temp, (struct threader *)args, sizeof(struct threader) );

    int j;
    int z;

    int i = temp.counter;
    int matrixSize = temp.matrixl;

    double temp2 = 0.0;

    for(j = i + 1; j<matrixSize; j++)
    {
        temp2 = a[j][i] / a[i][i];
        for(z = 0; z<matrixSize + 1; z++) // this will access memory beyond the bounds of 2d matrix a[]
        {
            a[j][z] = a[j][z] - temp2 * a[i][z];
        }
    }

    pthread_exit( NULL );
} // end function: parallelstuff


int checkargs(int argc, char* argv[])
{
    if(argc != 3)
    {
        fprintf(stderr, "Error: Usage: %s size threadNum\n", argv[0] );
        exit(1);
    }

    return( 0 );
} // end function: checkargs