2017-02-26 62 views
-1

這是我的代碼,幾個小時後我找不到這個錯誤。我在bash上運行它,並在行尾提供了正確的斐波那契輸出和分段錯誤11。但是當我使用Xcode來運行它時,沒有這樣的分段錯誤,但是在最後的正常返回0。C語言pthread程序中的段錯誤11

基本上我創建一個pthread來運行函數calculate,並且在完成後,我在主線程中運行顯示。

我很感激你的時間。

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

void *calculate(int n, int *arr) 
{ 
    for (int i = 0; i <= n; i++) 
    { 
     if (i == 1) 
      arr[i] = 1; 
     else if (i > 1) 
      arr[i] = arr[i - 1] + arr[i - 2]; 
    } 
    return NULL; 
} 

void display(int n, const int *arr) 
{ 
    for (int i = 0; i <= n; i++) 
    { 
     printf("%d ",arr[i]); 
    } 
} 

int main(int argc, const char* argv[]) 
{ 
    if (argc != 2) 
    { 
     printf("Wrong argument. You need ONE positive number as argument."); 
     return 1; 
    } 
    int number = atoi(argv[1]); 
    if (number < 0) 
    { 
     printf("Plese enter a positive integer."); 
     return 2; 
    } 
    else if (number == 0) 
    { 
     printf("0"); 
     return 0; 
    } 
    int *arr = (int*)malloc((number+1) * sizeof(int)); 
    arr[0] = 0; 
    pthread_attr_t attr; 
    pthread_t thread; 
    pthread_attr_init(&attr); 
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 
    pthread_create (&thread, &attr, calculate(number, arr), NULL); 
    display(number, arr); 
    free(arr); 
    return 0; 
} 
+0

您是否嘗試在退出前加入您的線程? –

回答

0

參見下面在pthread_create文檔(http://man7.org/linux/man-pages/man3/pthread_create.3.html):

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
        void *(*start_routine) (void *), void *arg); 

通知的參數到的start_routine被放置在 'ARG' PARAM - 一個不與參數直接調用該函數:

pthread_create()函數在調用過程中啓動一個新線程。新線程通過調用start_routine()開始執行; arg作爲start_routine()的唯一參數傳遞。

最後一點,你真的應該嘗試查看任何存儲它負責用於突變之前加入線程(在pthread_join):

int pthread_join(pthread_t thread, void **retval); 
+0

謝謝,我的問題幾乎解決了。最後一個問題是,我如何僅將一個參數傳遞給該函數,即int * arr?由於pthread_create函數的格式只接受帶void * type參數的函數。 –

+0

void * calculate(void * arg){int * arr =(int *)arg;解決了。非常感謝你! –

+0

最簡單的方法是創建一個結構體,將其地址轉換爲一個void指針以指向'args'。然後,在該函數中,將其轉換回正確的結構指針類型。 – Squirrel

0

要在松鼠答案擴大。您需要將實際功能傳遞給pthread_create,而不是在參數列表中調用它。否則,不僅在主線程中執行的函數還將返回值傳遞給pthread_create。該函數返回void*,所以它不會導致編譯錯誤。

您應該定義一個函數,它接受一個指針參數並返回void *並將其作爲第三個參數傳遞。然後要傳遞這些參數,可以定義一個結構體,該結構體可以保存所需的值,並將指針傳遞給pthread_create的最後一個參數。

在你的線程函數內部,你可以轉換回正確的指針類型並讀取值並在你的線程函數中使用它們。

這是一個完整的示例,顯示如何包裝多個參數並傳遞給pthread_create

我剛剛創建了一個結構來保存所需的參數並創建一個傳遞給pthread_create。在線程函數中,您將其重新轉換爲實數類型並讀取值。

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

struct params 
{ 
    int n; 
    int* arr; 
}; 

void calculate(int n, int *arr) 
{ 
    for (int i = 0; i <= n; i++) 
    { 
     if (i == 1) 
      arr[i] = 1; 
     else if (i > 1) 
      arr[i] = arr[i - 1] + arr[i - 2]; 
    } 
} 

// wrapper to pass function to thread 
void* calcwrap(void* data) 
{ 
    struct params* p = (struct params*)data; 
    calculate(p->n, p->arr); 
    return NULL; 
} 

void display(int n, const int *arr) 
{ 
    for (int i = 0; i <= n; i++) 
    { 
     printf("%d ",arr[i]); 
    } 
} 

int main(int argc, const char* argv[]) 
{ 
    if (argc != 2) 
    { 
     printf("Wrong argument. You need ONE positive number as argument."); 
     return 1; 
    } 
    int number = atoi(argv[1]); 
    if (number < 0) 
    { 
     printf("Plese enter an integer."); 
     return 2; 
    } 
    else if (number == 0) 
    { 
     printf("0"); 
     return 0; 
    } 
    int *arr = malloc((number+1) * sizeof(int)); 
    arr[0] = 0; 

    struct params thread_params = {number, arr}; 
    pthread_attr_t attr; 
    pthread_t thread; 

    pthread_attr_init(&attr); 

    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 
    pthread_create (&thread, &attr, calcwrap, &thread_params); 
    pthread_join(thread, NULL); 

    display(number, arr); 
    free(arr); 

    return 0; 
}