2011-06-24 36 views
1

我有这种情况:Python多线程

用Zope/Plone和一些mine python API创建的网页。有一个网页,称之为“a”,通过python方法调用一个数据库(Postgres)并返回一些信息。在页面“a”上,你可以修改数据库数据“离线”(我打算修改不是立即写入数据库,而是在你按下“保存”并调用python API方法后的第二个时刻)。所以,想象一下这种情况:一个名为“Sam”的用户加载页面并开始修改数据。同时,名为“Sara”的用户通过页面“a”点击“保存”修改数据库。现在,Sam没有实际的数据库数据:他会推“保存”并覆盖Sara的数据更改。

我会在我的网页上实时发出提醒。我以为我可以做这样的事情:

做一个AJAX调用,这是不可阻挡的,并继续与页面呈现。 AJAX调用一个python方法创建一个无限循环的线程(在“X”条件下)。当我在数据库上写入数据时,我会调用一个函数来改变“X条件”,停止线程并返回AJAX。

此外,我不能锁定数据库,因为我必须免费访问每个想要修改我的数据库的用户。

我的问题是:如何识别python线程?我刚刚看到,从Thread继承的类上的每个方法都需要“self”作为参数。此外,当我访问“a”页面时,我必须调用该线程,这将在代码中的某处(例如在“threads”模块中),但插入位于另一个模块上。那么,我怎样才能实现我的想法?

如果有人有另外一个设想,告诉我没有任何问题:)

回答

3

的你讨论问题的领域通常被称为“并发”。由于您的方法会在目标项目中的任何字段更改时警告或阻止用户更新,因此此方法通常称为“悲观并发”。做到这一点的一种方式是跟踪项目被选择时的样子,并且只有在数据库版本看起来与您选择的版本或自某个时间以来没有更新过的版本完全一样时才会更新(时间戳字段可能有帮助)。您还可以尝试乐观并发性,其中只检查一个用户已更新并保存回数据存储的字段未由其他用户更新。如果您选择支持并发的ORM库,这两种方法都是最简单的。

我最喜欢的python网络库是django,这里是关于你想要解决的相同情况的SO问题:Django: How can I protect against concurrent modification of database entries。我希望它有帮助。

以您建议的方式处理并发性是可行的,但在大多数情况下应该避免。在为具有广泛副作用并且没有统一数据访问的复杂对象(在系统的整个生命周期中存在大约5种数据访问方法,这是一个多彩的系统)的大型系统中添加并发性之前,我已经做到了这一点。这是容易出错并且处理并发性的复杂方式(我认为我有一个客户端应用程序,并在将数据表中的项标记为“签出”后启动了一个观察器线程,该数据表描述了对象的类型和标识符,检查出它的用户,当他们检查出它时,以及它在多长时间内是有效的,以防在检查完对象时检查对象的客户端无法检查它)。

如果设置为不使用ORM并在发生对项目发生更改时向用户显示消息,请尝试关闭上次更新的时间戳列,并让您​​的ajax调用检查以查看上次更新时间比第一次加载物品时要大。所以,如果你编写一个通用的方法来做到这一点,你只需要表名,主键和时间戳。

Web服务方法可能如下:

def is_most_current(table_name, id): 
    db = MySQLdb.connect(passwd="moonpie",db="thangs") 
    c=db.cursor() 
    c.execute("SELECT last_updated from %s where id = %s", (table_name, id)) 
    return c.fetchone() 

至于蟒蛇的多线程库,Python的线程是混乱和生产性能得益于差的问题与Python的全球连锁,你实际上可能要产生新的进程中很多情况下(多处理库相当,并行处理场景下性能更好)。就“自我”而言,这是一种Python引用你所处理的类的实例的pythonic惯例,很像C语言中的“this”。当你构造一个线程时,你可以通过给它一个唯一的名字来轻松识别它。有关更多信息,请参阅multiprocessingthreading文档。如果你可以避免这个问题的线程,我建议你这样做。

+0

你的回答很好,但我想告诉用户,在某个istant中,当他打开“a”页面时,另一个用户更新数据库。然后以propoer的方式更改字段(在“a”页面) – DonCallisto

+0

更新了我的答案,当我收到您的评论时,仍然键入最后几段。 – marr75