在Python中仅锁定一部分威胁

时间:2014-07-10 15:40:50

标签: python multithreading locking

我很擅长使用线程。

我在python中编写一个应用程序,需要检查一堆json对象的属性值是否在数据库中;如果没有,请插入它们并将消息发送到另一个应用程序。我想为每个线程处理这个对象。

如果多个对象具有数据库中缺少的相同属性值,我需要确保多个线程不会同时尝试添加它,因为这会混淆其他应用程序。所以,这样的事情将是有序的:

lock.acquire()
    if object.attribute not in database:
        insert value into database
        send message
    else:
        <process it>
lock.release()

但是,锁定应仅影响其指定对象具有相同属性值的线程,否则操作是安全的。

有什么好办法可以解决这个问题?

2 个答案:

答案 0 :(得分:2)

我的建议是维护一份&#34;目前被锁定的列表&#34;属性值并将其与条件变量锁结合使用。像这样:

cvlock.acquire()
while attribute_val in attribute_val_list:
  cvlock.wait()
attribute_val_list.append(attribute_val)
cvlock.release()

# Do your thing.

cvlock.acquire()
attribute_val_list.remove(attribute_val)
cvlock.notifyAll()
cvlock.release()

每当一个线程要将其对象添加到数据库时,它就会将属性值添加到attribute_val_list,该cvlock受多个线程的cvlock.wait()保护,试图立即修改它。当此线程正在运行时,具有相同属性值的任何其他线程将被重定向到attribute_val,直到第一个线程完成工作并从attribute_val_list中删除{{1}}。任何具有不同属性值的线程都可以正常进行。

https://docs.python.org/2/library/threading.html#condition-objects

答案 1 :(得分:1)

如果数据库中有适当的唯一约束,则无需使用任何锁定。只有在插入成功时才发送您的消息。无需线程级锁定。即使没有约束,也不能添加它们,并且可以为相同的值重复插入,您可以使用具有适当隔离级别的数据库事务。