2016-08-29 11 views
2

私が理解しているところから、グローバルインタープリタロックは、1つのスレッドだけがインタプリタにアクセスし、バイトコードを実行できるようにします。そうであれば、いつでも、1つのスレッドだけがインタプリタとそのメモリを使用します。なぜCPythonのスレッドセーフティについて心配する必要がありますか?

私は、2つのスレッドがインタープリタのメモリに同時にアクセスすることはできないため、レースケースが存在する可能性を排除することは公正だと考えていますが、データ構造が "スレッドセーフ" 。 GILをオフにして真のマルチスレッドを可能にするPythonインタプリタ(cythonのような)のすべての実装を網羅している可能性があります。

GILを有効にしていないインタープリタ環境でのスレッドの安全性の重要性を理解しています。しかし、CPythonでは、マルチスレッドのPythonコードを書くときにスレッドの安全性が奨励されるのはなぜですか? CPython環境で起こりうる悪化は何ですか?

答えて

6

もちろん、データ構造へのアクセスがではなく、であるため、競合状態がまだ発生する可能性があります。

if key not in dictionary: 
    # calculate new value 
    value = elaborate_calculation() 
    dictionary[key] = value 

not inテストが真を返した後にスレッドが任意の時点で切り替えることができ、かつ別:

は、キーを追加するために何かをするあなたが辞書に存在しているキーをテストすると言いますスレッドもキーが存在しないという結論に至ります。今では2つのスレッドが計算を行っており、どちらが勝つかはわかりません。

GILは、Pythonの内部インタープリタ状態を保護します。これは、Pythonコード自体が使用するデータ構造がロックされ、保護されていることを意味するものではありません。

0

重要な注意点:Pythonのマルチプロセッシングモジュールは、同じ変数へのアクセスが異なるプロセス間で同時に発生するという点で、GILにもかかわらずある程度の同期性があります。

これはあなたのデータを破壊する可能性があります。あるいは、少なくともスレッドフローの安全性が求められるコントロールフローを中断させる可能性があります。

なぜそれが起こるかについては、インタープリタが1つしかないにもかかわらず、共有メモリの同じ部分に同期してアクセスする2つのプリペイントされたコード片が停止していません(少なくとも私が知る限り)。行う場合は言う:

import multiprocessing 
def my_func(): 
    print("hello world") 
my_process=multiprocessing.Process (target=my_func, args=(,)) 
my_process.start() 
my_process.join() 

私の理解ではそれがmy_func(この場合は)interpritするのにかかる時間は、それが新しいプロセスを生成するのにかかるオーバーヘッドに埋葬されたということです。

この場合、データをコピーするために一時的に生成されるワーカースレッドが存在するため、「プロセス」という用語がより適しているため、データハンドシェイクが行われているため、実際はかなりプロセスが異なります伝統的な糸の産卵よりも(意図された馬術)。

こちらがお役に立てば幸いです。

関連する問題