doubleh3lix_lix剂和束的并发性和并行性

本文通过快餐店的厨师准备炸玉米饼的例子,深入浅出地讲解了并发和并行的区别,以及在Elixir和BEAM环境中如何实现这两者。Elixir基于Erlang虚拟机BEAM,能高效地处理并发和并行任务,提升系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

doubleh3lix

Imagine coming to an overcrowded fast food restaurant to order the best taco in the country and there’s only one cook working there. He prepares each taco one by one. Although the cook has an extra time while waiting until a tortilla heats up, he doesn’t start preparing another order until the first one is finished.

想象一下,到一家人满为患的快餐店订购全国最好的炸玉米饼,那里只有一位厨师。 他一步一步地准备每个炸玉米饼。 尽管厨师在等待玉米饼变热之前有额外的时间,但是直到第一个订单完成后,他才开始准备其他订单。

That’s your software without concurrency and parallelism.

那就是您的软件,没有并发性和并行性。

But what are the differences between those two? How are they handled in Elixir? Let’s start from the beginning.

但是两者之间有什么区别? 在Elixir中如何处理? 让我们从头开始。

并发与并行 (Concurrency vs parallelism)

In order to better understand the difference, let’s take a closer look at the above mentioned restaurant problem.

为了更好地理解差异,让我们仔细看一下上述餐厅问题。

Imagine that the cook has just received orders for two tacos. So far, he’s prepared each order separately which is preparing the first taco from the beginning to the end and then the same with the second one. However, he decides to do it at the same time. Steps that he’s taking look as follows:

想象一下,厨师刚刚收到了两份玉米饼的订单。 到目前为止,他已经分别准备了每个订单,这是从头到尾准备第一个炸玉米饼,然后与第二个炸玉米饼相同。 但是,他决定同时进行。 他正在采取的步骤如下所示:

  1. The cook’s preparing a tortilla for the first order,

    厨师的准备饼一阶

  2. The cook’s preparing a tortilla for the second order,

    厨师正在准备第二份玉米饼,

  3. For the first order, the cook’s putting vegetables and chicken on a tortilla,

    对于第一笔订单 厨师把蔬菜和鸡肉放在玉米饼上,

  4. For the second order, the cook’s putting vegetables and chicken on a tortilla,

    第二个命令是厨师将蔬菜和鸡肉放在玉米饼上,

  5. The cook’s putting a taco from the first order into the cooker to heat it up,

    厨师的投入塔科从第一顺序放进瓦煲内,以热起来,

  6. The cook’s putting a taco from the second order into the cooker to heat it up,

    厨师将第二份塔可乐中的炸玉米饼放入锅中加热,

  7. The taco from the first order is ready to serve,

    一阶的炸玉米饼随时可用

  8. The taco from the second order is ready to serve.

    来自第二订单的炸玉米饼随时可以使用。

Image for post

The action above represents a concurrent execution. The cook was preparing two orders at the same time, but in fact, he was switching back and forth between each process (preparing).

上面的动作表示并发执行。 厨师同时在准备两个订单,但实际上,他在每个过程之间来回切换(准备)。

We could wonder what the time difference between such an approach and preparing each order separately is. Imagine that before the cook serves a taco, he needs to wait until it heats up. It’d be a waste of time to wait doing nothing at that time.

我们想知道这种方法与分别准备每个订单之间的时差是多少。 想象一下,在厨师为炸玉米饼做饭之前,他需要等待直到炸玉米饼变热。 等待那时什么都不做会浪费时间。

Concurrency lets us start preparing another order while the first taco is heating up.

并发使我们可以在第一个炸玉米饼变热时开始准备另一个订单。

Image for post

What if the restaurant hired another cook for help? Then they would prepare tacos together. The main cook would prepare the first order and the newly hired employee would prepare the second order. Finally the process of preparing tacos would be finished twice as fast.

如果餐厅雇了另一位厨师帮忙怎么办? 然后他们将一起准备炸玉米饼。 主厨将准备第一份订单,新雇用的员工将准备第二份订单。 最终,准备炸玉米饼的过程将以两倍的速度完成。

Image for post

Such an approach, when the system is able to handle two or more processes exactly at the same time, is called parallel processing.

当系统能够完全同时处理两个或多个进程时,这种方法称为并行处理。

Note, you need at least two CPU cores to take advantage of the parallelism.

请注意,您至少需要两个CPU内核才能利用并行性。

To provide the highest performance, you can use both parallelism and concurrency at once.

为了提供最高的性能,您可以同时使用并行性和并发性。

那么BEAM是如何工作的呢? (So how exactly does BEAM work?)

Elixir is built on top of the Erlang Virtual Machine, also called BEAM (Bogdan’s Erlang Abstract Machine) and along with its Phoenix framework have all the benefits of Erlang. It means that we can create systems with a high concurrency and parallel processing which significantly influence their performance.

Elixir基于Erlang虚拟机(也称为BEAM(博格丹的Erlang抽象机)) 构建 ,并且其Phoenix框架具有Erlang的所有优点。 这意味着我们可以创建具有高并发性和并行处理能力的系统,从而显着影响其性能。

BEAM uses exactly one Operating System Thread from each processor’s core. On each thread, Erlang VM (I’ll use it interchangeably with BEAM) runs its own scheduler. In turn, each scheduler has its own run queue. A run queue contains awaiting processes which are pulled by the scheduler so they can be run.

BEAM仅使用每个处理器核心中的一个操作系统线程 。 在每个线程上Erlang VM (我将与BEAM互换使用)运行自己的调度程序 。 反过来,每个调度程序都有自己的运行队列。 运行队列包含等待的进程,这些进程由调度程序拉出,以便可以运行它们。

Image for post

Data is not shared between queues. There are no locks on data to avoid dirty reads/writes as each scheduler has its own, independent run queue. That’s why all the OS threads can be used all the time. Schedulers don’t have delays due to slowly running processes.

队列之间不共享数据。 由于每个调度程序都有自己的独立运行队列 ,因此没有数据锁可以避免脏读/写。 这就是为什么所有OS线程都可以一直使用的原因。 调度程序不会因进程运行缓慢而延迟。

When it comes to processes, they are not typical Operating System ones. They are Erlang processes which are lightweight (a newly spawned one uses 309 words of memory) compared to the threads and processes in OS. What’s more, each process leaves a small memory footprint, is fast to create and be terminated, and scheduling overhead is low.

当涉及到进程时,它们不是典型的操作系统进程。 与OS中的线程和进程相比,它们是轻量级的Erlang进程( 新生成的进程使用309个内存字 )。 而且,每个进程都占用很小的内存空间,创建和终止过程很快,并且调度开销很低。

BEAM is also responsible for distributing processes between run queues on the separate cores. It’s done by BEAM’s Load Balancer. The load balancer has its two techniques for balancing the incoming load: task stealing and migration. Using this logic, it takes tasks away from the run queues which are overloaded and migrates them to the ones with free resources.

BEAM还负责在各个​​内核上的运行队列之间分配进程。 这是由BEAM的负载均衡器完成的 。 负载均衡器有两种用于平衡传入负载的技术: 任务窃取迁移 。 使用此逻辑,它将任务从超载的运行队列中带走,并将其迁移到具有可用资源的队列中。

BEAM’s Load Balancer main purpose is to keep a high number of running processes allocated equally between each scheduler. It tries to use as few schedulers as possible so that none of the CPUs are overloaded.

BEAM的负载平衡器的主要目的是保持大量的运行进程在每个调度程序之间平均分配。 它尝试使用尽可能少的调度程序,以使所有CPU都不会过载。

加起来 (Summing up)

When building a fault tolerant and concurrent system, we should be aware of its possibilities. The knowledge about how the Erlang VM works can help us understand and solve everyday problems. What’s more, it gives us a chance to seize all its features to build reliable applications.

在构建容错和并发系统时,我们应该意识到它的可能性。 有关Erlang VM如何工作的知识可以帮助我们理解和解决日常问题。 而且,它使我们有机会抓住其所有功能来构建可靠的应用程序。

To get more details about how Erlang works, read the book entitled “The Erlang Runtime System” written by Erik Stenman or visit erlang.org to get acquainted with its documentation.

要获得有关Erlang的工作方式的更多详细信息,请阅读Erik Stenman撰写的题为“ The Erlang Runtime System ”的书,或访问erlang.org以了解其文档。

翻译自: https://medium.com/@patrykbak/concurrency-and-parallelism-with-elixir-and-beam-c683b2215c38

doubleh3lix

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值