2011-08-16 13 views
5

私はそれぞれの要求に対していくつかの「長い」タスクを実行するねじれたサーバーを持っています。各リクエストで私は共通のリソースにアクセスし、プロセス中に変更されます。各リクエストは元のデータから開始する必要があります。そのため、共通リソースでdeepcopyを使用しています(ロック取得の呼び出し中)。それは動作しますが、私はそれが十分に速くないと思います。私は、deepcopyが少し遅くなっていると感じています。ツイスト・スレッド・ハウツーでdeepcopyを避ける

リソースの突然変異を持つスレッド化されたねじれサーバーを扱う際にはどのような提案がありますか?

+0

十分速かったのは何でしたか?あなたのサーバーは毎秒N要求を処理できませんか? 1回のリクエストで時には時間がかかりますか?同時リクエストの数を増やすと、処理速度が低下しますか? – stderr

+0

1回のリクエストで時間がかかりすぎません。同時リクエストの数を増やすほど、遅くなることはありません。ひねり反応器のスレッドプールサイズは25に設定されています。 – Catalin

答えて

2

あなたが好きなら、他のスレッドプログラムと同じように、共有リソースへのアクセスをthreading.Lockと同期することができます。

ディープコピーの有無にかかわらずコードをベンチマークする価値があると思います。そうでなければ、パフォーマンスを最適化する前にパフォーマンスがどれほど良いか悪いかを判断することが重要です。たぶん遅い理由は、ディープコピーとは関係ありません。

私は、このリソースの周りにもっと細かい粒度のロックを使用できることを意味します。あなたのスレッドは共有リソースにアクセスする以上のことをしていると思います。作業を行っている複数のスレッドから利益を得ることができ、共有リソースへの書き込みを含む「クリティカルセクション」にアクセスを同期させることができます。また、共有リソースをスレッドセーフにすることを検討することもできます。たとえば、共有オブジェクト、SillyExampleFriendsList持っている場合:ここ

class SillyExampleFriendsList(object): 
    """Just manipulates a couple lists""" 
    def __init__(self): 
     self._lock = threading.RLock() 
     self._friends = [] 
     self._enemies = [] 

    def unfriend(self, x): 
     # we lock here to ensure that we're never in a state where 
     # someone might think 'x' is both our friend and our enemy. 
     self._lock.acquire() 
     self._friends.remove(x) 
     self._enemies.append(x) 
     self._lock.release() 

をポイントは、上記の目的は、潜在的にロックを慎重に使用してdeepcopyことなく、複数のスレッド間で共有できるだけのことです。これが必要となる可能性があるすべてのケースを特定することは自明ではなく、細かい粒度のロック戦略をデバッグするのが難しく、オーバーヘッドを導入する可能性もあります。

スレッド、ロック、またはディープコピーはまったく必要なく、コードをベンチマークすることなく、解決する必要のあるパフォーマンス上の問題があるかどうかはわかりません。私はあなたのコードがより速くなるべきである、あるいはそうでなければならないと考えているのは何か不思議です。

+0

"ベンチマークとプロファイルの最初の"センチメントの明確な+1。あまりにも頻繁に人々は、何かが実際には遅いことを知っても、間違ったものを最適化します。 – Glyph

+0

私がリソースへのアクセスをthreading.Lockと同期させると、私はシングルスレッドになります。事をベンチマークすることは間違いなくTODOです。 – Catalin

+0

リストの個々の操作はCPythonではスレッドセーフなので、ここの 'SharedList'は何も役に立ちません。 –

3

ワーカースレッドで可能な限り最小限のデータで操作してください。引数として必要なすべてのデータを渡し、すべての出力を、入力に対する突然変異ではなく、戻り値(Deferredが発生する値)として使用します。

次に、結果をリアクタスレッドの共通データ構造に統合します。

これにより、作業が孤立していると判断され、追加のロックが発生しなくなります(競合が発生し、結果が遅くなり、混乱を招くことになります)。

+0

共有するためのサンプル/チュートリアルがありますか? – Catalin

関連する問題