线程的“关键部分”是什么(在Python中)?
A thread enters the critical section by calling the acquire() method, which can either be blocking or non-blocking. A thread exits the critical section, by calling the release() method.
-Understanding Threading in Python, Linux Gazette
还有,锁的目的是什么?
"critical section"是一段代码,为了确保正确性,必须确保一次只能有一个控制线程在该部分中。一般来说,您需要一个关键部分来包含引用,这些引用将值写入内存中,以便在多个并发进程之间共享。
代码的关键部分是一次只能由一个线程执行的部分。以聊天服务器为例。如果每个连接(即每个最终用户)都有一个线程,那么一个“关键部分”是假脱机代码(向所有客户端发送传入消息)。如果不止一个线程试图一次假脱机一条消息,您将得到BfrIToS mANtwD pioemessages交织,这显然是没有好处的。
锁可以用来同步对关键部分(或一般资源)的访问。在我们的聊天服务器示例中,锁就像一个锁着的房间,里面有一台打字机。如果其中有一个线程(键入消息),则其他线程无法进入房间。一旦第一根线完成,他就打开房间,离开。然后另一根线可以进入房间(锁住它)。”“锁”的意思是“我得到房间”
其他人给出了很好的定义。下面是一个典型的例子:
假设
+=
运算符由三个子组件组成:如果没有
with account_balance_lock
语句,并且并行执行两个change_account_balance
调用,则可能会以危险的方式交错这三个子组件操作。假设您同时调用change_account_balance(100)
(AKA pos)和change_account_balance(-100)
(AKA neg)。这可能会发生:因为您没有强制操作以离散块的形式发生,所以可以有三种可能的结果(-100,0,100)。
with [lock]
语句是一个单独的、不可分割的操作,它说:“让我成为执行此代码块的唯一线程。如果有其他东西正在执行,那就很酷了——我会等的。”这确保了对account_balance
的更新是“线程安全”(并行安全)的。注意:此架构有一个警告:每次要操作
account_balance
以使代码保持线程安全,您必须记住获取account_balance_lock
(通过with
)。有办法让它不那么脆弱,但这是另一个问题的答案。编辑:回顾过去,可能需要指出的是,
with
语句隐式调用锁上的阻塞acquire
——这是上述线程对话框的“我将等待”部分。相比之下,一个非阻塞获取说,“如果我不能立即获取锁,让我知道”,然后依赖你检查你是否得到锁。我还想补充一点,锁的主要目的是保证获取的原子性(线程间
acquire
的不可分割性),而简单的布尔标记不能保证这一点。原子操作的语义可能也是另一个问题的内容。相关问题 更多 >
编程相关推荐