2012-01-15 20 views
10

可能性の重複:
Malloc thread-safe?malloc()はリエントラントではありませんが、スレッドセーフですか?

私は、 "Linuxのプログラミング・インタフェース" を読んでいる間、私は少し混乱していないです。

本書では、グローバルリンクリストのデータ構造を操作するため、mallocはリエントラントではないと言われていますが、mutexを使用してスレッドセーフになっています。

これは混乱しています:mutexを使用するとスレッドセーフであるため、同時に複数のスレッドが呼び出すことができます。なぜリエントラント関数ではないのですか? (再入可能とは、複数の呼び出し元が同時に呼び出すことができると言う場合)

もう1つの質問は、mallocはスレッドセーフなので、シグナルハンドラに入れることができるということですか? 私はこの答えが「はい」だと思いますが、この本によれば、シグナル・ハンドラにはリエントラントまたは非同期シグナル安全な関数しか入れられないと言われています。

誰でもこのことを私に説明できますか?

+0

mallocの実装にはミューテックスが含まれていますか? – Bingo

答えて

23

我々はリエントラントが、それは同時に複数の 呼び出し側によって

間違っ

を呼び出すことができることを意味すると言う場合。リエントラントは、を中断することができます。前回のインカネーションが終了する前に再度呼び出すことができます。想像malloc関数は次のようになります。それはのロックを解除する前、途中で中断し、他の誰かがmallocを呼び出している場合

lock(mutex); 

/* Stuff. */ 

unlock(mutex): 

どうなりますか?

  • 最初のコンテキストは、第1は、ミューテックスに
  • 二コンテキストブロックを完了するまで継続することはできませんし、最初のデッドロックだミューテックス

ロックを解除するまで継続することはできません。

もう1つの質問は、mallocはスレッドセーフなので、 をシグナルハンドラに入れることができますか?私は答えがイエスだと思う。

もう一度間違っている。上記の例を参照してください。メインプログラムがmallocを実行していて、関数が実際にハンドラを終了する前にmallocを呼び出すとします。

+0

おかげでcnicutar、答えは非常にクリアです! – kai

+0

@kai:POSIXの古いバージョン(2008年以前)がスレッドセーフであることを意味するために誤ってリエントラントを使用していたという事実によって、これらのコンセプトを混乱させる問題が悪化することに注意してください。 –

2

リエントラントとスレッドセーフは、2つの異なる概念です。リエントラント関数は非スレッドセーフで、スレッドセーフな関数は非リエントラントにすることができます。

Cのライブラリ関数は、再入可能であることは保証されず、シグナルハンドラからはリエントラント関数のみを呼び出すことができます。

+0

'スレッドセーフ '...できますか? –

+4

@iuliux:はい。一部のマシンでは、スタティック変数はスタックベースのローカル変数よりも高速です。入力時に静的変数をスタックにコピーし、静的変数を使用し、スタックからの変数をリエントラントに復元しますが、スレッドセーフではないコード。 – supercat

関連する問題