【问题标题】:Using iocp in a job pool在作业池中使用 iocp
【发布时间】:2010-07-19 22:55:02
【问题描述】:

当在作业/任务池中使用 iocp 来提供快速的工作器唤醒时,最大程度地减少向端口发送信号的开销的最佳方法是什么 - 即不必在每个队列操作中都这样做?

void Worker() { while(1) { for(int spin = 0; spin < 5000; ++spin) while(queue.Count > 0) queue.PopFront()();

    WaitOnCompletionPort();
}

}

...

queue.PushBack(someWork); // 决定何时发出完成端口信号,但避免在每个队列操作中都这样做?

例如,在上面的粗略代码草图中,如果您尝试避免在每次队列操作时向端口发送信号,则在工作排队和进入等待之间存在问题。

【问题讨论】:

    标签: windows task jobs pool iocp


    【解决方案1】:

    为什么不使用 IOCP 作为队列并将工作项直接发布到它?这样你就可以免费获得一个线程安全队列,并且可以完全移除你拥有的另一个队列?

    然后这个问题就会消失;)

    【讨论】:

    • 实际上,因为我正在尝试一种可能更有效的将工作项推送到队列中的方法,所以我试图避免为每个工作项发送端口信号。
    • 很公平,为什么不完全删除 IOCP 并改用信号量呢?或者,保留 IOCP,删除您的自定义队列并查看 GetQueuedCompletionStatusEx() 以一次删除多个完成以进行处理。
    • 据我所知,IOCP 比信号量更高效且可扩展。我只希望每个工作线程一次窃取一项工作 - 因为它一次只能运行一项任务/作业。问题在于决定何时在工作线程端口可能开始入睡之间发出信号。
    • 确实如此,它将确保您的队列是线程安全且高效的。如果您只希望每个工作人员一次处理一个工作项,那么只需使用 IOCP 作为您的队列。我不明白你关于“开始睡着”的评论。如果您使用 IOCP 并发布每个工作项,操作系统将通知最佳线程有可用的工作......我假设您已经分析了现有的基于 IOCP 的队列并有可以与您的新方式进行比较的数字?
    • 使用无锁队列,提交大量随机任务的效率显着提高了约 10-15%(这​​适用于通用任务系统,而不仅仅是响应网络事件等)。仅仅依靠 IOCP 对于完成大量工作的中等数量的任务来说还不错,但它的速度并不快。也许我最初的问题的答案是某种解决方案,有时可能会在不需要时意外唤醒一个线程 - 即一个已经运行的线程完成其任务并在另一个为其唤醒的线程之前抓取下一个工作。跨度>
    猜你喜欢
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多