【问题标题】:Notifying consumer when producer is done生产者完成后通知消费者
【发布时间】:2008-11-12 03:12:35
【问题描述】:

我正在从 ldap 读取大量数据,这些数据需要与数据库中的相应记录进行比较。为了尽量减少 SQL 查询的数量,我想将多个 ldap 记录批处理到一个查询中。

这一切都很简单:一个线程产生 ldap 结果,一个线程使用这些结果并运行 SQL 查询。

ldap_results = Queue.Queue(10) 定义生产者(): 对于 ldap_results() 中的结果: ldap_results.put(结果) 定义消费者(): 缓冲区 = [] 缓冲区大小 = 5 而真: 记录 = ldap_results.get() buffer.append(记录) 如果 len(buffer) >= buffer_size: do_sql(缓冲区) 缓冲区 = []

问题是:如果 ldap 只返回 3 个结果,而 buffer_size 是 5,它最终会永远阻塞。我意识到我可以在缓冲区中放入一些特殊的标记,例如 None"EOF",但这似乎是一个糟糕的设计:“迭代直到完成,哦,除非你看到这个特殊值,否则这意味着你”也完成了”。

我想出了两个替代的想法。首先是有一个共享的eof 变量,但我不知道如何正确同步它。

定义生产者(): 而数据: 缓冲区.put() eof = 真 定义消费者(): 虽然不是 eof: 缓冲区.get()

第二个是为生产者提供ProduceChunks(chunk_size) 方法,它会处理结果的批处理,但我不喜欢这样,因为它假设生产者知道如何最好地缓冲结果,当,真的,我认为这是消费者的责任。

有人有指导吗?

【问题讨论】:

    标签: producer-consumer concurrency


    【解决方案1】:

    我会遵循“让它运行、让它正确、让它快速、让它变得简单”的模式。

    如果没有特殊的“EOF”令牌,您能否正确实施?如果没有,那么你只需要使用 EOF 令牌,不要担心。是的,终止条件更复杂,但现在是“对”。

    【讨论】:

      【解决方案2】:

      “EOF”方法非常受人尊敬。让我们看一下 ANSI 字符串的缩影。空值是 EOF。这有什么不好?

      或者,让我们看看 BSTR 的缩影。第一个字节不是尾随的 null,而是告诉您字节是如何到来的。

      无论哪种方式都可以。

      没关系。

      【讨论】:

        猜你喜欢
        • 2017-03-26
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-25
        • 1970-01-01
        • 2014-10-16
        相关资源
        最近更新 更多