2016-07-28 8 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に表示されることがあります。ただし、動的に割り当てられたメモリはヒープからのものであり、解放するまで使用可能になるため、常に有効なデータはparamspin_thread_functionになります。

+0

'' pthread_create'の直後に 'params'が失われます。私は関数 'pin_monitor_create'の終わりにしか行かないとほとんど確信していました... ;-(基本的なスコープの概念がありませんか? – natenho

+0

いいえ、彼がもう一度書いたものを読んでください。' pin_monitor_create '。 –

+1

@natenho' pthread_create'の後に失われることはありません。 'pin_monitor_create'の後に失われます。スレッドスケジューラを直接制御することはできません。あなたが運が良ければ、メインスレッドが終了する前に 'pin_thread_function'スレッドが実行されると、あなたの文字列が表示されるか、マルチコアチップ上で2つのスレッドが本当に並列に実行される可能性があります。いくつかのスレッド同期技術を採用する必要があります。 – yano

2

私はpthreadsを(ちょうどかなりまだコメントすることはできません)については特に精通してないんだけど、あなた割り当てられたメモリをスタックするためのポインタをスレッドに渡しています。このスレッドは、関数呼び出しの処理によって最終的には詰まってしまいます。

+0

pin_monitor_createが終了するまで、paramsをスタックしてスタックしないでください。 – natenho

+0

パラメータは、ピンモニタの作成が終わるまで、スタック上に生きています。 –

+0

はい、pin_thread_function()に依存して、pin_monitor_create()が終了する前にコピーを作成しています。だから、時にはあなたがゴミや他の時間を稼ぐ理由があります。あなたはスケジューラに依存しています。 mallocingはこれを処理する適切な方法でしょう。 – ktb

関連する問題