分段错误而不改变我的程序

时间:2015-10-12 14:06:25

标签: c multithreading segmentation-fault pthreads

我正在尝试编写一个使用线程计算素数的程序,程序正在运行但没有给出所需的结果(它告诉所有数字都是素数)。今天我尝试再次运行该程序,即使我没有改变我的程序,我也遇到了分段错误。我尝试使用gdb来查找它何时发生,我认为它发生在pthread_join函数上。

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

int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;

int isPrime(int n){
    int i = 0;
    for(i=0; i < n; i++)
        if(n%i == 0)
            return 0;
    return 1;
}

void * threadPrime(void * arg){
    int* idxp = (int*)arg;
    int idx = *idxp;
    int start = idx* elements_per_thread;
    int finish = (idx+1)*elements_per_thread-1;
    int i;
        for(i=start; i<finish; i++)
            if(!isPrime(i))
                numbers[i]=0;
    pthread_exit(NULL);
}

int main(int argc, char* argv[]) {

  if (argc != 3) {
    printf("usage: %s largest_number number_threads\n", argv[0]);
    return 1;
  }

  int largest_number = atoi(argv[1]); // value of the largest number to test for primality
  int n_numbers = largest_number-1; // number of numbers to test
  n_threads = atoi(argv[2]);

  // create and fill vector of numbers to test  
  numbers = (int *)malloc(n_numbers*sizeof(int)) ;  // allocate a vector for n_numbers integers

  int i;
  for (i = 2; i <= largest_number; i++) 
    numbers[i-2] = i;

  int* id = (int *)malloc(n_threads*sizeof(int));
  // compute primes

 pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));
 for(i=0;i<n_threads;i++){
    id[i] = i;
    if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
       printf("Erro\n");
        exit(0);
    }
 }

 for(i=0;i<n_threads;i++){
    if(pthread_join(thid[i],NULL) != 0){
        printf("Erro\n");
        exit(0);
    }
 }

  // print result 
   printf("Primes:");
  int n_primes = 0;
  for (i = 0; i < n_numbers; i++) 
     if (numbers[i]) {
        n_primes++;
        printf (" %d", numbers[i]);
     }
  printf("\nTotal: %d primes\n", n_primes);

  return 0;         
}

问题解决了。正确的代码如下。

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

int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;

int isPrime(int n){
    int i = 0;
    for(i=2; i < n; i++)
        if(n%i == 0)
            return 0;
    return 1;
}

void * threadPrime(void * arg){
    int* idxp = (int*) arg;
    int idx = *idxp;
    int start = idx*elements_per_thread;
    int finish = (idx+1)*elements_per_thread;
    int i;
        for(i=start; i<=finish; i++)
            if(!isPrime(numbers[i]))
                numbers[i]=0;
    pthread_exit(NULL);
}

int main(int argc, char* argv[]) {

 if (argc != 3) {
    printf("usage: %s largest_number number_threads\n", argv[0]);
    return 1;
  }

  int largest_number = atoi(argv[1]); // value of the largest number to test for primality
  int n_numbers = largest_number-1; // number of numbers to test
  n_threads = atoi(argv[2]);

  // create and fill vector of numbers to test  
  numbers = (int *)malloc(n_numbers*sizeof(int)) ;  // allocate a vector for n_numbers integers

  int i;
  for (i = 2; i <= largest_number; i++) 
    numbers[i-2] = i;

  int* id;
  id = (int *)malloc(n_threads*sizeof(int));

  // compute primeselements_per_thread = n_numbers/n_threads;

  elements_per_thread = (n_numbers/n_threads)+1;

 pthread_t* thid = malloc(n_threads*sizeof(*thid));

 for(i=0;i<n_threads;i++){
    id[i] = i;
    if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
        printf("Erro\n");
        exit(0);
    }
 }

 for(i=0;i<n_threads;i++){  
    if(pthread_join(thid[i],NULL) != 0){
        printf("Erro\n");
        exit(0);
    }
 }

  // print result 
  printf("Primes:");
  int n_primes = 0;
  for (i = 0; i < n_numbers; i++) 
     if (numbers[i]) {
        n_primes++;
        printf (" %d", numbers[i]);
     }
  printf("\nTotal: %d primes\n", n_primes);

  return 0;         
}

2 个答案:

答案 0 :(得分:2)

您没有为thid分配适量的内存。这是您的分段错误的主要原因。

pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));

应该是

pthread_t* thid = malloc(n_threads*sizeof(p_thread));

(您不需要在C中投射malloc

这就是为什么我通常不使用显式类型作为sizeof的操作数,而只是使用变量名称,以便编译器可以推断出类型本身。

pthread_t* thid = malloc(n_threads*sizeof(*thid));

答案 1 :(得分:2)

有很多问题:

1)循环的起始索引应为2.否则,您将在此处出现除零错误:

for(i=0; i < n; i++) // should be i=2
   if(n%i == 0)
        return 0;

2)elements_per_thread根本没有设置。所以它将为0(因为它是一个全局变量)并且永远不会调用线程函数中的循环。在main()中设置它:

elements_per_thread = n_numbers/n_threads;

3)当你致电isPrime()时,你正在通过i。但你真的想通过numbers[i]。您还希望在素性测试中包含finish。所以它应该是

    for(i=start; i<=finish; i++)
        if(!isPrime(numbers[i]))
            numbers[i]=0;

4)线程数组的分配是错误的。它应该是

pthread_t* thid = malloc(n_threads * sizeof *thid);

有更有效的方法来测试质数(例如,您只需要检查n / 2以查看它是否为素数)。但是一旦你解决了上述问题,你就会有一个有效的代码,并考虑稍后改进它。