Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python CherryPy、线程和成员变量;潜在问题?_Python_Threadpool_Cherrypy - Fatal编程技术网

Python CherryPy、线程和成员变量;潜在问题?

Python CherryPy、线程和成员变量;潜在问题?,python,threadpool,cherrypy,Python,Threadpool,Cherrypy,假设我有以下简单的类: 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

假设我有以下简单的类:

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_成员可能等于一个东西,而从另一个线程访问时,它将是完全不同的东西。如果我错过了一些有详细记录的东西,我会提前道歉,但是一些谷歌搜索并没有真正找到我想要的东西。我知道对于这样一个简单的例子,有许多相对简单的方法可以解决这里的潜在问题(将变量的状态保存在数据库中,或者沿着这些路线),但这在我的实际用例中不起作用。

有丢失更新的危险。仅仅设置值不需要锁定,因为替换实例变量对于GIL来说是原子的(假设它不调用任何特殊方法等)。但递增或使用更复杂的变量将需要不同的方案使其线程安全

CherryPy中的共享访问通常与任何其他Python程序没有什么不同。与其在这里对所有这些选项进行长时间的重复,不如像上面提到的那样指导您,替换实例变量对于GIL来说可能是原子的,因此是线程安全的,但递增不是


CherryPy只在相反方向添加了一些帮助程序:当您不想共享时:
CherryPy.request
CherryPy.response
对象是新创建的(并正确销毁)对于每个请求/响应——如果您只想在请求期间保留数据,请随时将数据粘贴到
cherrypy.request.foo

有丢失更新的危险。仅仅设置值不需要锁定,因为替换实例变量对于GIL来说是原子的(假设它不调用任何特殊方法等)。但递增或使用更复杂的变量将需要不同的方案使其线程安全

CherryPy中的共享访问通常与任何其他Python程序没有什么不同。与其在这里对所有这些选项进行长时间的重复,不如像上面提到的那样指导您,替换实例变量对于GIL来说可能是原子的,因此是线程安全的,但递增不是


CherryPy只在相反方向添加了一些帮助程序:当您不想共享时:
CherryPy.request
CherryPy.response
对象是新创建的(并正确销毁)对于每个请求/响应——如果您只想在请求期间保留数据,请在
cherrypy.request.foo
中随意粘贴数据。

我想您的意思是:self.test_member=self.test_member+1?@fumanchu-我愿意,对此表示歉意。现在修好了。我想你的意思是:self.test_member=self.test_member+1?@fumanchu-我知道,为此道歉。现已修复。但是,
self.member=self.member+1
不是线程安全的,因为读取可以交错。@nneonneo的交错是指(假设self.member从0开始):(1)线程1读取self.member(2)线程2读取self.member(3)线程2将self.member设置为1(4)线程1也将self.member设置为1?@fumanchu-看起来该链接包含了很多我想要的东西。感谢您提供的信息。@repole:是的。之所以会发生这种交错,是因为在Python中获取变量、添加变量和设置变量都是单独的字节码操作。@nneonneo啊,是的,谢谢。我想“INPLACE\u ADD只是一个op”,但它当然与LOAD\u ATTR和STORE\u ATTR分开。捕捉得很好。但是,
self.member=self.member+1
不是线程安全的,因为读取可以交错。@nneonneo的交错是指(假设self.member从0开始):(1)线程1读取self.member(2)线程2读取self.member(3)线程2将self.member设置为1(4)线程1也将self.member设置为1?@fumanchu-看起来该链接包含了很多我想要的东西。感谢您提供的信息。@repole:是的。之所以会发生这种交错,是因为在Python中获取变量、添加变量和设置变量都是单独的字节码操作。@nneonneo啊,是的,谢谢。我想“INPLACE\u ADD只是一个op”,但它当然与LOAD\u ATTR和STORE\u ATTR分开。抢手货