2012-03-08 58 views
2

這是我第一次使用pthreads。我遇到了麻煩,因爲有時候我的程序段發生故障,有時卻沒有。我的程序中有幾個函數用於執行一些基本任務(用C語言編寫),例如創建鏈接列表,將項目添加到列表以及從列表中刪除項目。每個函數創建它自己的列表副本,所以我不認爲它們彼此交互,因此不需要互斥鎖。無論如何,下面是我的代碼,如果任何人有任何想法,或者如果有任何「共同」的初學者線程錯誤。帶鏈接列表的pthread分段錯誤 - 初學者

我運行每個函數1000次並行,某些時候seg錯誤,有時不是。我注意到它只發生在這三個功能的組合中。

的過程是這樣的: - 創建線程 - 並行 運行的線程 - 每個線程調用虛函數來執行任務的時間 給定數 - 即虛擬函數還調用等功能

我認爲它可能與內存使用/分配有關,因爲所有這些功能都與創建/刪除鏈接列表節點有關。非常感謝。

下面是創建和加入:

pthread_create(&t7, NULL, (void*)&p4, (void*)var); 
pthread_create(&t8, NULL, (void*)&p5a, (void*)var); 
pthread_create(&t9, NULL, (void*)&p5b, (void*)var); 
pthread_join(t7, NULL); 
pthread_join(t8, NULL); 
pthread_join(t9, NULL); 

這裏是虛擬功能:

void p4(int *nptr){ 
    int n = *nptr; 
    // Get current time 
    struct timeval t0, t1; 
    gettimeofday(&t0,0); 

    int i = 0; 
    LIST *list = (LIST*)malloc(sizeof(LIST)); 
     for(i=0;i<n;i++){ 
    f4(list); 
    deleteList(list); 
    } 
    // Get current time and find time elapsed 
    gettimeofday(&t1,0); 
    float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; 
     printf("Successful execution of p4 in %f microseconds.\n", elapsed); 
    free(list); 
} 
void p5a(int *nptr){ 
    int n = *nptr; 
    LIST *list = (LIST*)malloc(sizeof(LIST)); 
    f4(list); 
    // Get current time 
    struct timeval t0, t1; 
    gettimeofday(&t0,0); 

    int i = 0; 
     for(i=0;i<n;i++){ 
    f5a(list); 
    } 
    // Get current time and find time elapsed 
    gettimeofday(&t1,0); 
    float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; 
    printf("Successful execution of p5a in %f microseconds.\n", elapsed); 
} 
void p5b(int *nptr){ 
    int n = *nptr; 
    LIST *list = (LIST*)malloc(sizeof(LIST)); 
    f4(list); 
    int i = 0; 
     for(i=0;i<n;i++){ 
    f5a(list); 
    } 
    // Get current time 
    struct timeval t0, t1; 
    gettimeofday(&t0,0); 
    for(i=0;i<n;i++){ 
    f5b(list); 
    } 
    // Get current time and find time elapsed 
    gettimeofday(&t1,0); 
    float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; 
    printf("Successful execution of p5b in %f microseconds.\n", elapsed); 
} 

下面是執行常規任務使用的功能:

// FUNCTION: initialize a linked list with pointers and insert a last element 
void f4(LIST *L1){ 
    // initialize an empty linked list if L1 = null 
    if(L1->head == NULL){ 
    NODE *n = (NODE *)malloc(sizeof(NODE)); 
    L1->head = n; 
    L1->tail = n; 
    L1->tail->next = NULL; 
    n->data = 1; 
    } 
    // traverse the linked list to the end 
    NODE *iter = L1->head; 
    while(iter->next != NULL) 
    iter = iter->next; 
    // insert a new 2 element 
    NODE *new = (NODE *)malloc(sizeof(NODE)); 
    new->data = 2; // arbitrary for testing 
    new->next = NULL; 
    iter->next = new; 
    L1->tail = new; 
} 

// FUNCTION: add an item to the end of a list (queue) 
void f5a(LIST *list){ 
    NODE *new = (NODE *)malloc(sizeof(NODE)); 
    new->data = 999; 
    new->next = NULL; 
    list->tail->next = new; 
    list->tail = new; 
} 

// FUNCTION: remove an item from the beginning of a list (queue) 
void f5b(LIST *list){ 
    NODE *remove = list->head; 
    list->head = list->head->next; 
    free(remove); 
} 
+0

我懷疑線程有什麼與此有關。它似乎不像你分享任何內存。我會考慮更好地測試你的列表函數。 (另外,jeebus,將它們命名爲描述性的!) – Collin 2012-03-08 13:30:28

+0

它似乎並不重要,但儘量不要使用保留關鍵字作爲變量名:'new'關鍵字在C++中保留。我知道你的程序是用C語言編寫的,而不是用C++編寫的,但是......以防萬一。也許有一天某人(例如你)會想將它移植到C++ ... – sirgeorge 2012-03-08 13:35:35

+0

你可以發佈deleteList代碼嗎? – Jay 2012-03-08 13:49:42

回答

3

如果您閱讀malloc手冊頁,你可以看到,並沒有初始化分配的內存爲0.所以,你malloc內存在p4,p5ap5b功能。在此之後,您可以輸入f4函數,但不會有任何已初始化的LIST爭用。

p4函數中檢查有效指針if(L1->head == NULL)但它可能不爲空。因此,您不需要爲L1->head分配內存,在此功能之後,您可以在f5b函數中釋放未分配的指針。

建議:

  • 總是初始化分配的區域。
  • 經常檢查malloc返回指針
+0

謝謝你的洞察力。這是問題。我將頭部初始化爲NULL,並且都被原諒了。 – mathjacks 2012-03-08 14:18:10