2016-07-28 92 views
1

以下功能不起作用。 pin_thread_function有時會收到垃圾,而不是結構數據。哪裏不對?我知道這是一些基本範圍相關的問題,但我無法解釋。如何將本地結構作爲參數傳遞給pthread_create?

typedef void (*state_callback_t)(int state); 

struct pin_thread_params 
{ 
    char pin[3 + 1]; 
    state_callback_t callback_onchange; 
}; 

extern int pin_monitor_create(const char * pin, 
     state_callback_t callback_onchange) 
{ 
    int ret; 
    unsigned long int thread; 
    struct pin_thread_params params; 

    //Setup struct 
    strcpy(params.pin, "123"); 
    params.callback_onchange = callback_onchange; 

    //Create thread with struc as parameter 
    ret = pthread_create(&thread, NULL, pin_thread_function, &params); 
    if (!ret) 
    { 
     ret = pthread_detach(thread); 
    } 

    return ret; 
} 

static void * pin_thread_function(void * context) 
{ 
    struct pin_thread_params params; 
    memcpy(&params, context, sizeof(params)); 

    //Sometimes the correct string, most time garbage 
    printf("Started monitoring %s", params.pin); 
} 

當params爲在pthread_create之前malloc分配,一切工作正常,像這樣:

... 
    struct pin_thread_params * params; 

    //Setup struct with malloc 
    params = malloc(sizeof(struct pin_thread_params)); 
    strcpy(params->pin, "123"); 
    params->callback_onchange = callback_onchange; 
... 

回答

3

struct pin_thread_params params是靜態分配和它的地址是安全使用一次,它的範圍是在(即pin_monitor_create後返回)。可能會發生線程執行有時在pin_monitor_create退出之前啓動並且您在params中看到有效數據的情況。但是,動態分配的內存來自堆,並且在您釋放它之前一直可用,因此您始終可以在內獲得有效數據,內部爲pin_thread_function

+0

因此,'params'在'pthread_create'之後丟失。我幾乎可以肯定它只會在函數'pin_monitor_create'的末尾消失...... ;-(我是否遺漏了一些基本的範圍概念? – natenho

+0

不,請再讀一遍他寫的東西,它在'pin_monitor_create '' –

+1

@natenho它在'pthread_create'後不會丟失,它在'pin_monitor_create'之後丟失了,你不能直接控制線程調度器,如果主線程在'pin_thread_function'線程運行之前完成'pin_thread_create',垃圾數據如果你很幸運並且'pin_thread_function'線程在主線程完成之前執行,你會看到你的字符串,或者在多核芯片上,這2個線程真的可以並行運行。你必須使用一些線程同步技術。 – yano

2

我不是特別懂行約並行線程(不能隨便發表意見相當尚未),但你正在傳遞一個指向堆棧分配的內存的線程,這個線程最終會被進程函數調用破壞。

+0

不應該PARAMS和堆棧住pin_monitor_create結束? – natenho

+0

堆棧上的參數直到引腳監視器創建結束。 –

+0

是的,但是您要根據pin_thread_function()在pin_monitor_create()完成之前進行復制。這就是爲什麼_sometimes_你得到垃圾和其他時間的原因。您取決於調度程序。 mallocing會處理這個問題的正確方法。 – ktb

相關問題