1

C での呼び出しに関する概念をもう少し明確にしたかったのですmalloc()。メイン スレッドが任意の数のワーカー スレッド (pthread) を生成するマルチスレッド アプリケーションがあります。次に、各ワーカー スレッドは無限関数を実行します (含まれる関数は別の.cファイルからのもので、while (1) を実装します)。これにより、継続的なネットワーク I/O を担当します。

スレッドごとにハッシュ テーブルが必要だったので、glib が提供するハッシュ マップを使用しました。私がしたことは、各スレッドの関数内でハッシュ マップを初期化し、バックエンドで構造体に初期メモリを割り当て、必要に応じて拡張できるようにすることでした。

アプリケーションを実行すると、セグメンテーション違反や構造体にメモリを割り当てることができないなどのエラーが発生しました。エラーの原因がハッシュ マップにメモリを割り当てられなかったことが原因であることが判明するまで、しばらく時間がかかりました。私が考えたのは(今でも考えています)、各スレッドには独自のメモリ空間があり、独自のメモリブロック内のそれぞれのハッシュマップにメモリブロックを割り当てることです。mutex(sudo コード) のようなハッシュ マップの初期化の前後にロックを使用することで、エラーを修正できました。

lock mutex
initialize hashmap
unlock mutex

各スレッドで呼び出されるハッシュ マップを初期化するためのコードは次のとおりです。

 GHashTable *g_hash_table;
  g_hash_table = g_hash_table_new (g_int_hash, g_int_equal);

問題は解決しましたが、この後少し混乱しました。各スレッドには実装する関数用の独自のメモリ空間があり、独自のメモリを割り当てているときに他のスレッドと競合してはならないため、ロックを使用せずにこの問題が発生するのはなぜですか。すべてのガイダンスに感謝します。

ありがとう。

4

1 に答える 1

2

各スレッドには独自のメモリ空間がありません。すべてのスレッドがプロセス内のすべてのスレッドのメモリにアクセスできます。

とはいえ、各スレッドはこのスペース内で独自のスタックが割り当てられるため、auto-var は誤用されなければ問題なく、malloc/free はスレッドセーフである必要があるため、動的に割り当てられるハッシュ マップ (auto-pointer によってポイントされる)スレッドスタック上で)、問題ないはずです。

選択肢がある場合は、ライブラリのスレッド セーフ バージョンに対してリンクしていることを確認してください。

ミューテックス ロックは必要ありません。それが問題を解決しているのであれば、その通りです。malloc/free のようなものは、スレッドセーフであるべきときにスレッドセーフではありません。

hashmap コードが auto または malloced ストレージのみを参照していることは確かですか? グローバル/スタティックが侵入していませんか?

于 2012-04-21T18:52:17.653 に答える