简体   繁体   English

使用pthread库时出现分段错误

[英]segmentation fault while using pthread library

I am a newbie to threading and i am trying to change the sequential program of travelling salesman problem (dynamic programming) to parallel program using threading in c. 我是线程的新手,我正在尝试使用c中的线程将旅行推销员问题的顺序程序(动态编程)更改为并行程序。

#include <stdio.h>
#include <limits.h>

#define size 10 //maximum 10 cities
#define min(a,b) (a > b ? b : a)
#define sizePOW  1024    // 2^10

//Space complexity: O(n * 2^n)
//Time complexity: O(n^2 * 2^n)

int n; npow;
int g[size][sizePOW];
int p[size][sizePOW];
int adj[size][size];

int compute(int start, int set) {
    int masked, mask, temp, i;
    int result = INT_MAX; //result stores the minimum 

    if (g[start][set] != -1) //memoization DP top-down,check for repeated subproblem
        return g[start][set];

    for (i = 0; i < n; i++) {   //npow-1 because we always exclude "home" vertex from our set
            mask = (npow - 1) - (1 << i);  //remove ith vertex from this set
            masked = set & mask;
            if (masked != set) { //in case same set is generated(because ith vertex was not present in the set hence we get the same set on removal) eg 12&13=12
                temp = adj[start][i] + compute(i, masked); //compute the removed set
                if (temp < result)
                    result = temp, 
                    p[start][set] = i; //removing ith vertex gave us minimum
            }
        }
        return g[start][set] = result; //return minimum
}
void getpath(int start, int set) {
    if (p[start][set] == -1) 
       return; //reached null set

    int x = p[start][set];
    int mask = (npow - 1) - (1 << x);
    int masked = set & mask; //remove p from set
    printf("%d ", x);
    getpath(x, masked);
}
void TSP() {    
    int i, j;
    //g(i,S) is length of shortest path starting at i visiting all vertices in S and ending at 1
    for (i = 0; i < n; i++)
        for (j = 0; j < npow; j++) 
                g[i][j] = p[i][j] = -1; 
    for (i = 0; i < n; i++)
         g[i][0] = adj[i][0]; //g(i,nullset)= direct edge between (i,1)

    int result = compute(0, npow - 2);//npow-2 to exclude our "home" vertex
    printf("Tour cost:%d\n", result);
    printf("Tour path:\n0 ");
    getpath(0, npow - 2);
    printf("0\n");
}

int main(void) {
    int i, j;
    printf("Enter number of cities\n");
    scanf("%d",&n);
    npow=(int)pow(2, n);//bit number required to represent all possible sets
    printf("Enter the adjacency matrix\n");
    for(i = 0; i < n; i++)
       for(j = 0; j < n; j++)
          scanf("%d", &adj[i][j]);
    TSP();
    return 0;
}

This is the sequential program from ideone code . 这是来自ideone代码的顺序程序。 Here is my parallel code for this 这是我的并行代码

#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include<limits.h>

#define size 10 //maximum 10 cities
#define min(a,b) a > b ? b:a
#define sizePOW 1024 // 2^10

struct threadargs {
    int a, b;
    int *c;
};
//Space complexity: O(n * 2^n)
//Time complexity: O(n^2 * 2^n)

int n, npow;
int g[size][sizePOW];
int p[size][sizePOW];
int adj[size][size];

void printMatrix() {
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 16; j++) {
            printf("%d ",g[i][j]);

        printf("\n");
    }
    printf("\n\n");
}

void *compute(void *args) { 
    int masked, mask, i, start, set; 
    int result = INT_MAX; //result stores the minimum 
    struct threadargs *recvargs = (struct threadargs *) args;
    start = recvargs->a;
    set = recvargs->b;
    int *retval = recvargs->c;

    if (g[start][set] != -1) { //memoization DP top-down,check for repeated subproblem
        *retval += g[start][set];
        return;
    }

    printMatrix();
    //sleep(1);
    int temp[n];

    for (i = 0; i < n; i++)
        temp[i] = INT_MAX;

    pthread_t threads[n];
    struct threadargs arguments[n];
    int running_thread_count = 0;

    for (i = 0; i < n; i++) 
       threads[i] == -1;

    for (i = 0; i < n; i++) {   //npow-1 because we always exclude "home" vertex from our set
            mask= (npow - 1) - (1 << i); //remove ith vertex from this set
            masked = set & mask;
            //printf("hello world");
            if (masked != set)//in case same set is generated(because ith vertex was not present in the set hence we get the same set on removal) eg 12&13=12
            {   
                temp[i] = adj[start][i];
                arguments[i].a = i;
                arguments[i].b = masked;
                arguments[i].c = &temp[i];
                pthread_create(&threads[i], NULL, compute, (void *)&arguments[i] );
                running_thread_count++;

            }
        }

        for (i = 0; i < n; i++) {
            if (pthread_kill(threads[i], 0) != ESRCH)
                pthread_join(threads[i], NULL);
        }

        int ith = 0;
        result = temp[0];
        for (i = 1; i < n; i++) {
            if(temp[i] < result) {
                result = temp[i];
                ith = i;
            }
        }
        p[start][set] = ith;
        if (result != INT_MAX)
            g[start][set] = result; //return minimum
        *retval += g[start][set];
}

void getpath(int start,int set)
{
    if (p[start][set] == -1)
       return; //reached null set
    int x = p[start][set];
    int mask= (npow - 1) - (1 << x);
    int masked = set & mask;//remove p from set
    printf("%d ",x);
    getpath(x, masked);
}
void TSP()
{   int i, j;
    //g(i,S) is length of shortest path starting at i visiting all vertices in S and ending at 1
    for(i=0; i < n; i++)
        for( j = 0; j < npow; j++) 
                g[i][j] = p[i][j] = -1; 
    for (i = 0; i < n; i++)
        g[i][0] = adj[i][0]; //g(i,nullset)= direct edge between (i,1)

    int result;
    struct threadargs arguments;
    arguments.a = 0;
    arguments.b = npow-2;
    arguments.c = &result;
    compute((void *) &arguments);//npow-2 to exclude our "home" vertex
    printf("Tour cost:%d\n",result);
    printf("Tour path:\n0 ");
    getpath(0,npow-2);
    printf("0\n");
}
int main(void) {
    int i, j;
    printf("Enter number of cities\n");
    scanf("%d", &n);
    npow=(int)pow(2, n);//bit number required to represent all possible sets
    printf("Enter the adjacency matrix\n");
    for (i = 0; i < n; i++)
       for (j = 0; j < n; j++)
            scanf("%d", &adj[i][j]);
    TSP();
    return 0;
}

But I am getting segmentation fault while trying to execute this code. 但是我在尝试执行此代码时遇到分段错误。 Following is the output of the gdb 以下是gdb的输出

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78bf63e in pthread_join (threadid=4196128, 
    thread_return=0x0) at pthread_join.c:85
85  pthread_join.c: No such file or directory.
(gdb) backtrace
#0  0x00007ffff78bf63e in pthread_join (threadid=4196128, 
    thread_return=0x0) at pthread_join.c:85
#1  0x0000000000400b36 in compute (args=0x7fffffffde90) at tsp3.c:69
#2  0x0000000000400db2 in TSP () at tsp3.c:107
#3  0x0000000000400ec8 in main () at tsp3.c:120
(gdb) 

I know this will not give any noticeable performance gain but I want to try this. 我知道这不会带来任何明显的性能提升,但是我想尝试一下。 Thanks in advance. 提前致谢。

**edit : ** I have rectified the errors but now I am facing new errors.I am getting correct answer when program runs but if I delete the line `printMatrix() , I get segmentation fault. 我已经纠正了错误,但是现在我遇到了新的错误。程序运行时我得到了正确的答案,但是如果删除`printMatrix()行,则会出现分段错误。 The gdb log is as follows gdb日志如下

(gdb) backtrace
#0  __pthread_kill (threadid=0, signo=0)
    at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:42
#1  0x0000000000400c85 in compute (args=0x7ffff74eede0) at tsp3.c:79
#2  0x00007ffff78be182 in start_thread (arg=0x7ffff64ed700)
    at pthread_create.c:312
#3  0x00007ffff75eaefd in clone ()
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) 

why is this happening. 为什么会这样。 Please explain. 请解释。 Thanks in advance. 提前致谢。

You are creating threads in compare function, and you pass compare as thread function, that's chaos. 您正在用compare函数创建线程,然后将compare作为线程函数传递,这很混乱。 You maybe exceed available number of threads. 您可能超出了可用线程数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM