2016-10-19 13 views
1

(これはAre static inline functions thread safe?に従います)関数ポインタはスレッドセーフですか?

シナリオ:2つの並列スレッドで実行され、コードの点で同じで、異なるデータを処理する大きなコードを記述しました。私は非決定的な結果を見ている。 2つのスレッドのいずれかを無効にすると、結果は確定的になります。このコードの中で私はいくつかの関数ポインタを使用していますが、それらが私の問題の原因である可能性があるかどうかを理解したいと思います。

関数ポインタはCではスレッドセーフであるか?他の方法では、内部に静的変数がなく、ローカル変数と入力パラメータのみがある場合、2つのスレッドからの同時呼び出しは予測できない動作を引き起こしますか?

例コード:

void foo(int param1, int* out); 
void bar(int param1, int* out); 

typedef void (*fooBarFuncP_t)(int, int*); 

static inline fooBarFuncP_t getFooBar(int selection) { 
    switch (selection) { 
     case 0: 
      return &foo; 
     case 1: 
     default: 
      return &bar; 
    } 
} 

void test(int selection, int x, int* y) { 
    (*getFooBar(selection))(x,y); 
} 

  • yは、発信者が2つのスレッドのために別々に割り当てられる

    その実装、foobar持ちで
    • のみ局所、非静的変数
    • 試験の範囲

    これはスレッドセーフですか?そうでない場合は、この問題に対してどのような解決策がありますか?

  • +0

    データレースはありません。 – 2501

    +0

    'foo'と' bar'の間には相互作用はありません。一見すると、私はここで何の問題も見ません。 –

    +0

    @MichaelWalz良い点。 'foo'と' bar'はバッファを共有します(入力パラメータの一部です)。しかし、バッファは2つのスレッドに対して別々に割り当てられ、 'foo'と' bar'は同じスレッド*内で同時に呼び出されることはありません*。 (私は二重チェックしています) – Antonio

    答えて

    1

    関数ポインタの呼び出し/使用は、スレッドセーフに関する関数の使用と同じです。 この例では、スレッドセーフの問題はありません(指定した条件の下で)。あなたのコード内の任意のデータ競合があるかどう

    • チェック:あなたはまだスレッドの安全性に関連する問題、いくつかの提案を持っていると仮定すると

    • ヘッダー、ライブラリ関数、サードパーティの関数などに関連する静的変数があるかどうかを確認します(あなたは何も言わなかったと思いますが、まだいくつか見逃している可能性があります)。

    • Helgrindのコードを実行してください。

    0

    スレッドセーフティの点で、関数ポインタと通常の変数には違いはありません。変数が複数のスレッドで共有されていて、少なくとも変数へのスレッド書き込みであれば、それを保護する必要があります。

    関数が呼び出される場所は、その関数のスレッドセーフティとは関係ありません。重要なのは、その関数を実行するスレッドだけです。複数のスレッドが同じ関数を呼び出す場合、どのようにスレッドを実行しても、その関数はスレッドセーフである必要があります。

    +0

    私の例の関数はスレッドセーフですか? – Antonio

    +0

    @Antonio "test"関数は共有リソースに何もしないので、安全ではない理由はありません。この例がスレッドセーフであるかどうかは、2つの呼び出される関数がスレッドセーフであるかどうかによって決まります。 – Lundin

    関連する問題