2

次の簡単なクラスがあるとしましょう。

import cherrypy
import os

class test:
  test_member = 0;
  def __init__(self):
    return
  def index(self):
    self.test_member = self.test_member + 1
    return str(self.test_member)
  index.exposed = True

conf = os.path.join(os.path.dirname(__file__), 'config.ini')

if __name__ == '__main__':
  # CherryPy always starts with app.root when trying to map request URIs
  # to objects, so we need to mount a request handler root. A request
  # to '/' will be mapped to HelloWorld().index().
  cherrypy.config.update({'server.socket_host': '0.0.0.0'})
  cherrypy.quickstart(test(), config=conf)
else:
  # This branch is for the test suite; you can ignore it.
  cherrypy.config.update({'server.socket_host': '0.0.0.0'})
  cherrypy.tree.mount(test(), config=conf)

したがって、最初にインデックスページを開くと、1に戻り、次に2に戻り、次に3、4というように続きます。私の質問は次のとおりです。

  • これには、特にスレッドと複数の人が同時にページにアクセスする場合に、大きな危険がありますか?
  • 問題を防ぐために、書き込まれるたびに何らかの方法でメンバー変数をロックする必要がありますか?
  • 整数のような単純なものではなく、メンバーとして基本的なデータ型(自分の複雑なクラスなど)を使用している場合、何か変更はありますか?

CherryPyを使用したスレッド化がどのように機能するかを完全には理解していません。この単純な例での私の懸念は、あるスレッドではtest_memberが1つのものに等しくなり、別のスレッドからアクセスするとまったく異なるものになることだと思います。十分に文書化されているものが不足している場合は、事前に謝罪しますが、一部のグーグルでは、探していたものが実際には表示されませんでした。このような単純な例では、ここで潜在的な問題を解決できる比較的簡単なパスがいくつかあることを理解しています(データベース内の変数の状態、またはそれらの線に沿ったものを保持します)が、実際のユースケースでは機能しません。

4

1 に答える 1

4

更新が失われる危険性があります。インスタンス変数の置き換えはGILに関してアトミックであるため(特別なメソッドなどを呼び出さないと仮定して)、値を設定するだけでロックする必要はありません。ただし、より複雑な変数をインクリメントまたは使用するには、それらをスレッドセーフにするために異なるスキームが必要になります。

CherryPyの共有アクセスは、通常、他のPythonプログラムと何ら変わりはありません。ここでこれらすべてのオプションを長時間再ハッシュするのではなく、http://effbot.org/zone/thread-synchronization.htmに誘導することをお勧めします。前述のように、インスタンス変数の置き換えは、GILに関しておそらくアトミックであり、それによってスレッドセーフですが、インクリメントはそうではありません。

CherryPyは、反対方向にいくつかのヘルパーを追加するだけです。共有したくないcherrypy.request場合:およびcherrypy.responseオブジェクトは、要求/応答ごとに新しく作成されます(適切に破棄されます)。データcherrypy.request.fooを保持したい場合は、データを自由に貼り付けてください。リクエストの期間中のみ。

于 2012-09-10T14:53:36.100 に答える