多pthreads分段故障(核心转储)无法检测到问题

时间:2012-12-03 15:03:25

标签: c pthreads segmentation-fault

我被困在thSegmentation故障(核心倾倒) 是错误的,我的想法已经不多了。请帮我发现问题所在。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <semaphore.h>

#define workTime 5
#define workersLimitNr 3

struct dataBlock{
    struct node *root;
    int listSize;
    int forIndex;
};

struct node { // std linked list node
    int value;
    int worker;
    struct node *next;
};

int slots = 0; // only 3 threads are allowed to access the list
int availableCheck(){   // check if thread can acces the list
    if(slots < 3) return 0;
    else return -1;
}

pthread_mutex_t mutp = PTHREAD_MUTEX_INITIALIZER;   //condvar mutex
pthread_cond_t  condvar = PTHREAD_COND_INITIALIZER;   //condvar

void * worker( void *data ){
    struct dataBlock *inData = (struct dataBlock *) data;
    struct node *root = inData->root;
    int listSize =  inData->listSize;
    int forIndex = inData ->forIndex;
    free(data);
    printf( "*    Thread id: %lu    forID:  %d  workerNode: \n",pthread_self(),forIndex); 

    pthread_mutex_lock( &mutp );
    if(availableCheck() < 0){
        printf( " ^^^ List not available yet... \n" ); 
        pthread_cond_wait( &condvar, &mutp );
    } 
    struct node *it = root;

    printf( "_ _ _ _forID_ %d\n", forIndex );
    do{
        if(forIndex == it->worker){
            printf("valid for sqrt  forIndex %d == it->worker %d\n",forIndex, it->worker );
            if(it->value > 2){
                while(it->value != 1)
                it->value = sqrt(it->value);
                // it->value = it->value - 1;
            }
        }
        it = it->next;
        printf("->val: %d   \n", it->value);
    }while(it !=  NULL);

    pthread_cond_signal( &condvar ); // 
    pthread_mutex_unlock( &mutp ); 
    return NULL;
}

int main( int argc, char *argv[] ){
    if ( argc != 3 ){
        printf( "Programm must be called with \n NR of elements and NR of workers! \n " );
        exit( 1 );
    }

    int i;
    struct node *root;
    struct node *iterator;  

//prepare list for task
    int listSize = atoi(argv[1]);
    int nrWorkers = atoi(argv[2]);
    root = malloc(sizeof( struct node) );

    root->value = rand() % 100;
    root->worker = 0;
    iterator = root;

    for( i=1; i<listSize; i++ ){
        iterator->next = malloc(sizeof(struct node));
        iterator = iterator->next;
        iterator->value = rand() % 100;
        iterator->worker = i % nrWorkers;
        printf("node #%d worker: %d  value: %d\n", i, iterator->worker,iterator->value);
    }
    iterator->next = NULL;
    printf("? List got populated\n");

// Create all threads to parse the link list
    int ret;    
    printf("workersInput: %d\n",nrWorkers);
    pthread_mutex_init(&mutp,NULL);

    pthread_t w_thread;
    pthread_t* w_threads = malloc(nrWorkers * sizeof(w_thread));


    for( i=0; i < nrWorkers; i++ ){         
        struct dataBlock *data = malloc(sizeof(struct dataBlock));
        data->root = root;
        data->listSize = listSize;
        data->forIndex = i;
        ret = pthread_create ( &w_threads[i], NULL, worker, (void *) data );
        if( ret ) {
            perror("Thread creation fail");
            exit(2);    
        }   
        printf("in for, ret= %d\n",ret);

    } 

    for ( i = 0; i < nrWorkers; i++){
        pthread_join(w_threads[i],NULL);
    }
    iterator = root;
    for ( i = 0; i < listSize; i++){
        printf("val: %d  worker: %d _  ", iterator->value, iterator->worker);
        iterator = iterator->next;
    }

    free(root);
    free(iterator);
    return 0;
}

终端编译+程序运行:

bogdan@bogdan-VirtualBox:~/dos/threads$ gcc -Wall -g  s.c -o s -pthread -lm
s.c: In function ‘worker’:
s.c:35:6: warning: unused variable ‘listSize’ [-Wunused-variable]
bogdan@bogdan-VirtualBox:~/dos/threads$ ./s 4 4
node #1 worker: 1  value: 86
node #2 worker: 2  value: 77
node #3 worker: 3  value: 15
? List got populated
workersInput: 4
in for, ret= 0
in for, ret= 0
in for, ret= 0
in for, ret= 0
*    Thread id: 3050646336    forID:  3  workerNode: 
_ _ _ _forID_ 3
->val: 86   
->val: 77   
->val: 15   
valid for sqrt  forIndex 3 == it->worker 3
Segmentation fault (core dumped)

PS:while(iterator->next != NULL)更改线程工作器函数中的while条件并在列表创建iterator->next == NULL;

1 个答案:

答案 0 :(得分:3)

你的printf崩溃了整个事情:

do {
    // ...
    it = it->next;
    printf("->val: %d   \n", it->value);
} while(it !=  NULL);

在某些时候,就在您的退出条件到达之前,itNULL,因此您通过尝试打印该值来取消引用空指针。

删除printf应使程序正常运行。另外,不要忘记free()

Pro-tip:使用Valgrind检测无效的内存访问。