2013-04-05 4 views
1

Je me suis tapé la tête sur un mur pendant plusieurs heures, essayant maintenant de trouver ce qui cause cette erreur de segmentation.Segfault résultant de pthread?

J'ai trouvé que la segfault se produit régulièrement sur la ligne pthread_mutex_lock(lock) (38). J'ai placé deux instructions d'impression entourant la serrure cependant, seulement un d'entre eux imprime, qui est ma justification pour conclure que le segfault se produit à cette instruction. Est-ce que j'utilise le verrou mutex correctement ou est-ce que je fais une erreur avec mes tableaux (buffer[] et numbermarker[]?

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

int* numbermarker = NULL; 
int* buffer = NULL; 
int pullposition = 0; 
int placeposition = 1; 
pthread_mutex_t *lock; 
int ceiling; 

/*This method places one of the primes in the buffer. It 
offers a safe way to manage where the next value will be placed*/ 
void placevalue(int value) 
{ 
    buffer[placeposition] = value; 
    placeposition++; 
} 

/*This method pulls the next prime and increments to the next prime in the list*/ 
int takevalue() 
{ 
    pullposition++; 
    return buffer[pullposition-1]; 
} 


void* threadmethod() 
{ 
    int k; 
    int l; 
    int firstval; 
    while(1) 
    { 
     while(numbermarker[buffer[pullposition]-1]==0) 
     { 
      printf("flag1 \n"); 
      pthread_mutex_lock(lock); 
      printf("flag2 \n"); 
       numbermarker[buffer[pullposition]-1] = 1; 
       l = takevalue(); 
      pthread_mutex_unlock(lock); 
      firstval = 1; 
      for(k=l+1;k<=ceiling;k++) 
      { 
       if(k%l != 0) 
       { 
        if(firstval) 
        { 
         placevalue(k); 
         firstval = 0; 
        } 
       } 
       else 
       { 
        numbermarker[k-1] = 1; 
       } 
      } 
     } 
    } 
} 


int main() 
{ 
int numthreads; 
int i; 

printf("Enter number of threads: \n"); 
scanf("%d", &numthreads); 

printf("Enter the highest value to check \n"); 
scanf("%d", &ceiling); 

    /* This will hold 1's and 0's. 
     1 = number has been checked or is 
      confirmed not to be a prime 
     0 = number is a possible prime 

    The idea behind these values is that the next 
    prime can always be identified by the 0 with 
    the lowest index*/ 
numbermarker = (int*)malloc(sizeof(int)*(ceiling)); 

    /*This will hold the primes as they are found*/ 
buffer = (int*)malloc(sizeof(int)*(ceiling)); 

for(i=0; i<ceiling; i++) 
{ 
    if(i<1) 
    { 
     numbermarker[i] = 1; 
    } 
    else 
    { 
     numbermarker[i] = 0; 
    } 

    buffer[i]=0; 
    printf("%d \n",numbermarker[i]); 
} 

placevalue(2); 

pthread_t **tid = (pthread_t **) malloc(sizeof(pthread_t *) * numthreads); 


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

    tid[i] = (pthread_t *) malloc(sizeof(pthread_t)); 
} 

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

    if(pthread_create(tid[i], 
       NULL, 
       threadmethod, 
       NULL)) 
    { 

     printf("Could not create thread \n"); 
     exit(-1); 
    } 
}  


int not_done = 1; 
int sum; 
while(not_done) 
{ 
    sum = 0;  
    for(i=0; i<ceiling; i++) 
    { 
     sum += numbermarker[i]; 
    } 
    if(sum == ceiling) 
     not_done = 0; 
} 
for(i=0;i<numthreads;i++) 
{ 
    if(pthread_join(*tid[i], NULL)) 
    { 
     printf("Error Joining with thread \n"); 
    } 
    free(tid[i]); 
} 
free(tid); 




for(i=0;i<ceiling;i++) 
{ 
    if(buffer[i] != 0); 
     printf("%d \n", i); 
} 
free(buffer); 
free(numbermarker); 
buffer=NULL; 
numbermarker=NULL; 


return(0); 

}

+0

S'il vous plaît [n » t cast la valeur de retour de 'malloc()' dans C] (http: // stack overflow.com/a/605858/28169). Merci. – unwind

Répondre

5

lock est un pointeur uninitialised. Vous devez allouer de la mémoire pour ensuite initialiser un mutex avant de le verrouiller. La solution la plus simple serait de changer

pthread_mutex_t *lock; 

à

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

et (depuis lock n'est plus un pointeur)

pthread_mutex_lock(lock); 
.... 
pthread_mutex_unlock(lock); 

à

pthread_mutex_lock(&lock); 
.... 
pthread_mutex_unlock(&lock); 
+0

Et pthread_mutex_lock (& ​​lock) –

+0

@jimmcnamara Vous venez de me battre pour elle, maintenant modifié pour inclure cette – simonc

+0

je l'ai fait quelques recherches et a trouvé un autre correctif qui maintient les verrous comme pointeurs: je avais besoin pour allouer de l'espace pour la serrure, utilisez alors la méthode d'initialisation pthread: 'lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t));' 'pthread_mutex_init (verrou, NULL);' –