2014-04-24 128 views
-2

我使用pthreads做了Histogram,經過長時間的努力後..最後它說'Segmentation Fault(Core Dumped)'。不幸的是我有這條線p =(struct1 *)malloc(sizeof(struct1));從命令行獲得值的結構變量..所以這被清除了..感謝@DNT讓我知道..分割錯誤(核心轉儲)C編程pthreads直方圖

現在,當我嘗試執行下列程序..它有時會顯示輸出,有時它會發送到which_bin函數並打印以下內容:

輸出類型1(這不是正確的輸出): Data = 0.000000不屬於bin! 退出

輸出型2(幾乎HISTO的正確的輸出隨時間通過螺紋採取): 10.000-28.000: 28.000-46.000: 46.000-64.000: 64.000-82.000: 82.000-100.000:XXXXXXXXXX 該代碼將定時把0.000415秒

我的疑問句的是,爲什麼同樣的前衛跑時表現出不同的輸出..我很困惑的其所以然尋找..

這裏是我的代碼..

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include "timer.h" 
void Usage(char prog_name[]); 



//void Get_args(void *p); 
void Gen_data(void *p); 
void Gen_bins(void *p); 
int Which_bin(void *p); 
void Print_histo(void *p); 


void func(void *p); 

struct test 
{ 
    int bin_count, i, bin; 
    float min_meas, max_meas; 
    float* bin_maxes; 
    int* bin_counts; 
    int data_count; 
    float* data; 
}; 

typedef struct test struct1; 

int main(int argc, char* argv[]) 
{ 
    double start, finish, elapsed; 
    GET_TIME(start); 

    struct1 *p; 
    pthread_t th1, th2, th3; 

    p=(struct1 *)malloc(sizeof(struct1)); 
    if (argc != 5) 
     Usage(argv[0]); 
    p->bin_count = strtol(argv[1], NULL, 10); 
    p->min_meas = strtof(argv[2], NULL); 
    p->max_meas = strtof(argv[3], NULL); 
    p->data_count = strtol(argv[4], NULL, 10); 

    p->bin_maxes = malloc(p->bin_count*sizeof(float)); 
    p->bin_counts = malloc(p->bin_count*sizeof(int)); 
    p->data = malloc(p->data_count*sizeof(float)); 


    pthread_create(&th1,NULL,(void*) Gen_data,(void*) p); 
    pthread_create(&th2,NULL,(void*) Gen_bins,(void*) p); 
    pthread_create(&th3,NULL,(void*) func,(void*) p); 
    printf("Hi\n"); 


    pthread_join(th1,NULL); 
    pthread_join(th2,NULL); 
    pthread_join(th3,NULL); 


    Print_histo(p); 
    free(p->data); 
    free(p->bin_maxes); 
    free(p->bin_counts); 

    GET_TIME(finish); 
    elapsed = finish - start; 
    printf("The code to be timed took %f seconds\n", elapsed); 
    return 0; 
} /* main */ 

void func(void *p) 
{ 
    int i; 
    struct1 *args; 
    args=(struct1*)p; 

    for (i = 0; i < args->data_count; i++) 
    { 
     args->bin = Which_bin(args); 
     args->bin_counts[args->bin]++; 
    } 

    # ifdef DEBUG 
     printf("bin_counts = "); 
     for (i = 0; i < args->bin_count; i++) 
      printf("%d ", args->bin_counts[i]); 
     printf("\n"); 
    # endif 
} 

/*--------------------------------------------------------------------- 
* Function: Usage 
* Purpose: Print a message showing how to run program and quit 
* In arg: prog_name: the name of the program from the command line 
*/ 
void Usage(char prog_name[] /* in */) 
{ 
    fprintf(stderr, "usage: %s ", prog_name); 
    fprintf(stderr, "<bin_count> <min_meas> <max_meas> <data_count>\n"); 
    exit(0); 
} /* Usage */ 


void Gen_data(void *p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int i; 
    srandom(0); 
    for (i = 0; i < args->data_count; i++) 
     args->data[i] = args->min_meas + (args->max_meas - args->min_meas)*random()/((double) RAND_MAX); 

    #ifdef DEBUG 
     printf("data = "); 
     for (i = 0; i < args->data_count; i++) 
      printf("%4.3f ", args->data[i]); 
     printf("\n"); 
    #endif 
} /* Gen_data */ 


void Gen_bins(void* p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    float bin_width; 
    int i; 
    bin_width = (args->max_meas - args->min_meas)/args->bin_count; 

    for (i = 0; i < args->bin_count; i++) 
    { 
     args->bin_maxes[i] = args->min_meas + (i+1)*bin_width; 
     args->bin_counts[i] = 0; 
    } 

    # ifdef DEBUG 
     printf("bin_maxes = "); 
     for (i = 0; i < args->bin_count; i++) 
      printf("%4.3f ", args->bin_maxes[i]); 
     printf("\n"); 
    # endif 
} 

int Which_bin(void* p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int bottom = 0, top = args->bin_count-1; 
    int mid; 
    float bin_max, bin_min; 

    while (bottom <= top) 
    { 
     mid = (bottom + top)/2; 
     bin_max = args->bin_maxes[mid]; 
     bin_min = (mid == 0) ? args->min_meas: args->bin_maxes[mid-1]; 
     if (*(args->data) >= bin_max) 
      bottom = mid+1; 
     else if (*(args->data) < bin_min) 
      top = mid-1; 
     else 
      return mid; 
    } 
    fprintf(stderr, "Data = %f doesn't belong to a bin!\n", args->data); 
    fprintf(stderr, "Quitting\n"); 
    exit(-1); 
} 

void Print_histo(void *p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int i, j; 
    float bin_max, bin_min; 

    for (i = 0; i < args->bin_count; i++) 
    { 
     bin_max = args->bin_maxes[i]; 
     bin_min = (i == 0) ? args->min_meas: args->bin_maxes[i-1]; 
     printf("%.3f-%.3f:\t", bin_min, bin_max); 
     for (j = 0; j < args->bin_counts[i]; j++) 
      printf("X"); 
     printf("\n"); 
    } 
} 

/* Print_histo */ 

我想知道該程序是否在邏輯上錯誤?如果在這種情況下它在邏輯上是錯誤的,那麼爲什麼它有時會顯示直方圖輸出。謝謝!

+5

請使用調試器來縮小您的問題。 – Mat

+1

在進行高級編程(如多線程)之前,您需要學習C的基礎知識。如果你從main()和向下讀你的程序,你應該能夠在幾秒鐘內找到bug。 – Lundin

回答

1

如何之前 'P' 移動這一行

p=(struct1 *)malloc(sizeof(struct1)); 

用於分配的成員。

+0

謝謝!現在我沒有看到分段錯誤(核心轉儲),而不是正確的輸出:)我必須再次開始我的鬥爭:) – Deepak

+0

您可能想從一開始就仔細檢查代碼中的邏輯,並且確保它實際上做你想做的事情。一種方法是自己運行每個例程而不用線程來查看它是否正常工作,最後當你驗證了正確性時,再把它們放在一起:) – DNT

+0

首先,我創建了串行直方圖程序,然後當我看到正確性它..然後我開始與pthreads ..謝謝! – Deepak