是否有任何理由锁定队列?

Posted

技术标签:

【中文标题】是否有任何理由锁定队列?【英文标题】:Is there any reason to lock a queue? 【发布时间】:2018-10-30 17:16:46 【问题描述】:

我只是想知道是否有任何理由要锁定队列。我正在开发一个应用程序,该应用程序具有多个读取和写入数据库的线程。为了减少流量,我想在任何给定点减少对该数据库的调用量(我知道许多数据库已经可以处理一些流量)。为读/写请求创建一个队列并且只执行顶部的请求然后用锁保护队列的推送和弹出命令是否有意义?对每个读/写调用进行锁定是否足够?无论如何,锁不是由操作系统实现为“队列”吗?这个“队列”的大小可能是一个问题,还是有任何其他原因我不会单独使用锁? 谢谢!

【问题讨论】:

这个问题太宽泛了:很大程度上取决于架构、每秒应该支持多少请求、预期延迟是多少、SLA 是多少等。此外,在 Java 中我们有 @987654322 @ 可以使用。其他语言可能有类似的产品(通过库/框架)。也不清楚为什么要锁定读取。 我在连接到谷歌云数据存储的树莓派 3 上使用 Python、Linux 操作系统,我没有确定它应该支持的每秒请求数,但可能有 25 个左右的连接可以同时进来。我不想锁定读取以确保数据的一致性吗? @jspcal 建议使用信号量来限制并发操作是否足够? 我很抱歉不清楚。我正在运行一个 python 脚本,它将在树莓派 3 上的 Linux 操作系统之上运行。python 脚本获取外部数据并使数据库读/写到 Google Cloud Datastore。 在单个进程中,内置的Semaphore正是你所需要的:docs.python.org/3/library/… 完美,非常感谢。您是否碰巧知道我是否也想使用信号量来读取数据库,还是这样做有点过头了? 【参考方案1】:

您可以限制参与数据库请求的线程数,或者如果由于您的应用的性质而这不可行,您可以使用更精细的方法来限制对共享资源的访问。在python中,可以使用内置的semaphore objects进行线程间同步。对于进程间同步(或线程间),您将使用posix_ipc。这取决于您的服务的执行模型是什么。

大多数数据库客户端不需要任何应用程序级别的限制。在典型的系统中,数据库连接将被池化,连接管理器将负责获取可用连接。在内部,这通常涉及某种带有超时的队列,以防止无限期地等待。然后,数据库本身将处理每个连接进行的各个操作的调度。

但是,信号量是一种信号原语,可用于限制并发操作的数量:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Semaphore.html

也可以将任务建模为涉及共享队列的producer-consumer problem,但是除了生产者之外,您还必须处理管理消费者线程的额外复杂性。

【讨论】:

以上是关于是否有任何理由锁定队列?的主要内容,如果未能解决你的问题,请参考以下文章

使用消息队列的理由

使用消息队列(MQ)的 10 个理由!

使用消息队列的 10 个理由--IPC通信

使用多处理队列、池和锁定的简单示例

如何锁定队列变量地址而不是使用临界区?

是否需要锁定阅读对象?