披萨、线程、等待、通知。这是什么意思?
我有两种方法(在 C# 中):
List<Pizza> CookPizza(List<Order>);
List<HappyCustomers> DeliverPizza(List<Pizza>);
这些操作没有公共对象(除了从一个方法传递到另一个方法的披萨之外),并且是线程安全的。它们每个都需要几秒钟的时间来执行,并且它们每个都使用不同的资源(烤箱与汽车)。因此,我想同时运行它们。
如何在这些约束下组织线程:
我一开始就知道所有订单(比如说,我有 100,000 个订单)。一个订单可以包含多个披萨,在这些披萨煮熟之前我不知道任何订单中有多少个披萨。 (我知道很奇怪)。一般来说,一个订单有 1 个披萨,但最多可以有 10 个。
活跃披萨的数量一般不应超过 100 个。这包括新鲜烹制的披萨和正在配送的披萨。这是一个软限制,所以我可以超过它一些(例如,当一个大订单被煮熟时)。硬限制可能接近 500 个。
当给予大量工作时,这两种操作都会更有效。一般来说,CookPizza 在给出至少 20 个订单时效率最高。当提供至少 50 个披萨时,送货披萨的效率最高。也就是说,如果我向这些方法提供的项目少于这些数量,我会看到性能下降。如果仅剩这些,那么使用较少的项目就可以了。
我遇到的主要问题是这些方法可能需要如何相互等待。
- DeliverPizza 可能需要等待 CookPizza 完成 50。CookPizza
- 可能需要等待 DeliverPizza 将活动披萨的数量减少到 100。
I have two methods (in C#):
List<Pizza> CookPizza(List<Order>);
List<HappyCustomers> DeliverPizza(List<Pizza>);
These operations have no common objects (aside from the pizzas that are passed from one to the other), and are thread-safe. They each take several seconds to execute and they each use different resources (oven vs car). As such, I want to run them at the same time.
How do I organize the threading with these constraints:
I know all of the Orders at the start (say, I have 100,000 of them). An Order can consist of multiple Pizzas and I don't know how many Pizzas are in any Order until after those Pizzas are cooked. (wierd I know). Generally an Order has 1 Pizza, but there can be as many as 10.
The number of active Pizzas should not generally exceed 100. This includes Pizzas freshly cooked and Pizzas being delivered. This is a soft limit, so I can exceed it some (for example, when a big Order was cooked). The hard limit is probably closer to 500.
Both of the operations are more efficient when they are given a lot of work. Generally, CookPizza is most efficient when given at least 20 Orders. Deliver Pizza is most efficient when given at least 50 Pizzas. That is to say, I will see performance degrade if I give fewer items to those methods than those amounts. It's fine to use fewer items if that's all that is left.
The main issue I'm stuggling with is how the methods may need to wait on each other.
- DeliverPizza might need to wait around for CookPizza to complete 50.
- CookPizza might need to wait around for DeliverPizza to reduce the number of active Pizzas to 100.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我首先使用基于事件的模型来解决这个问题。
假设我们有一个接受订单的
PizzaDispatcher
对象。调度程序从初始空状态开始调用CookPizza
并提供一定数量的订单。当披萨煮熟后,CookPizza
函数会通知调度程序披萨已煮熟(可能通过您作为参数提供的回调)。当交付披萨时,DeliverPizza
函数会执行相同的操作。PizzaDispatcher
现在将拥有足够的信息,根据煮熟的披萨和未交付的披萨数量来决定何时以及应上交多少披萨进行烹饪或交付。这可以重构为使用事件而不是回调等,但我发布它是为了这个想法,而不是实现的细节。
I 'd approach this problem using an event-based model to begin with.
Let's say we have a
PizzaDispatcher
object which is given the orders. The dispatcher begins callingCookPizza
with a set number of orders from the initial empty state. When pizzas are cooked theCookPizza
function notifies the dispatcher that a pizza has been cooked (perhaps by a callback that you provide as a parameter). When a pizza is delivered theDeliverPizza
function does the same.The
PizzaDispatcher
would now have enough information to decide when and how many pizzas should be turned in for cooking or for delivery based on the number of cooked pizzas and outstanding deliveries.This can be refactored to using events instead of callbacks etc, but I 'm posting it for the idea, not the specifics of the implementation.
您需要一个并发缓冲区 - 可能是一个并发队列,并且您可能需要多个。您需要一个并发的订单队列。您使用并发队列调用 CookOrder。当 CookOrder 返回时,您可以使用队列的新内容再次调用它。如果您愿意的话,在这里您只能发布前 100 条或其他内容。这里,订单被队列有效地批处理,并且 CookOrder 始终运行。然后你用披萨再次重复这个过程。
You want a concurrent buffer- probably a concurrent queue, and you may need several. You want a concurrent queue of orders. You call CookOrder with the concurrent queue. When CookOrder returns, you call it again with the new contents of the queue. Here you can only post the first 100 items or something if you want. Here the Orders are effectively batched by the queue and CookOrder is always running. Then you repeat the process again with Pizzas.
似乎您所需要的只是一个
PizzaManager
来决定首先烹饪什么Pizza
订单,然后将它们传递给DeliveryBoy
以便他们被交付。然后,一旦DeliveryBoy
DeliversPizza
,他就会向PizzaManager
报告以检索下一个Pizza
订单。PizzaManager
负责处理与优化烹饪和配送订单优先级相关的所有数学运算。DeliveryBoy
可能会将PizzaManager
作为委托
。It seems like all you need is a
PizzaManager
that decides whatPizza
order to cook first, and then passes them along to theDeliveryBoy
for them to be delivered. Then once theDeliveryBoy
DeliversPizza
, then he reports back to thePizzaManager
to retrieve the nextPizza
order. ThePizzaManager
takes care of all math related to optimizing the priority of which orders to cook and deliver. TheDeliveryBoy
would probably have thePizzaManager
as adelegate
.一种想法
是向 Pizza 添加一个成员变量来跟踪 is_cooked。
然后在 CookPizza 过程中,完成后将该成员设置为 true,
然后在 DeliverPizza 期间,在继续之前检查该成员。
one thought
add a member variable to Pizza to track is_cooked.
then during CookPizza, set that member to true when done,
then during DeliverPizza, check that member before proceeding.