文章

Nim中的多任务处理

这是一系列关于Nim生态系统中的一个主题的文章,到目前为止,关于这个主题的文章还相当少。即线程、异步操作和通信。

首先,我们需要充分掌握我们将要讨论的概念。这个领域中的所有术语都很容易混淆,因此我们先从一些简单的定义开始。为了更好地理解这些术语,让我们先来看看现代计算机是如何工作的,现在是学习计算机科学101的时候了。

现代计算机的工作原理是将磁盘、网卡(现在通常内置在主板中)、图形卡等硬件连接到CPU。这些硬件通过中断进行通信,顾名思义,中断CPU的执行,CPU处理来自设备的数据。这样做是因为硬件的速度通常比CPU本身慢很多个数量级,而且可以避免多余的轮询。CPU有一个或多个物理内核。每个物理内核一次只能做一件事,但即使在单核机器上,我们也可以运行多个线程。线程是一个执行片段,通常是整个程序或程序的特定部分。一个或多个线程属于同一个进程,也就是运行可执行文件时创建的进程。

说完这些,让我们来看看并发、并行、异步操作和通信的不同概念。即使在只有一个物理内核的机器上,也可以同时运行多个程序。其工作原理并不是让两个程序同时执行,而是在两个程序之间快速切换,造成同时执行的假象。这就是所谓的并发性。虽然它不会带来任何性能上的好处,但却能让我们在程序在后台执行计算的同时,拥有一个反应灵敏的图形用户界面。

另一方面,只有当CPU拥有一个以上物理内核(或在某种程度上使用超线程和类似架构)时,才会出现并行性。与并发相同的是,执行被分成多个线程,但线程之间的切换并不是很快,而是可以同时运行。现代操作系统当然会同时使用这两种功能,因此线程既可以运行在同一个内核上,也可以运行在两个不同的内核上。这意味着我们可以利用它们来提高程序的性能。

除此之外,我们还有异步操作。由于与CPU相比,文件操作和网络操作的速度非常慢,因此我们可以使用异步版本的常规文件和网络程序。这些程序会轮询操作系统操作是否完成,并允许我们在等待时做其他事情。这可以用来提高性能,但仅限于处理I/O绑定问题时。

在处理并行执行的多个执行线程时,我们会面临一些通常在顺序程序中不会遇到的额外问题。所有这些都是因为我们现在要共享资源和内存。其中最明显的问题与内存有关,我们可以在线程之间传递指向内存的指针,但如果我们不小心,最终可能会绊倒其他线程,从而产生奇怪的错误。解决这个问题的方法通常是使用锁、原子操作或特殊数据结构,以确保在这种情况下的安全性。

现在我们来看看如何在 Nim 中实现这些功能。为了尽可能保持文章的可读性,我将这些主题分成了多篇文章,将来可能还会有更多文章:

  1. 异步执行
  2. 多线程
  3. 通信

注:这是我在硬盘里放了很久的系列文章,因为除了这篇入门文章和异步文章外,我还没有写更多的文章。我本想至少写完多线程这篇文章后再发表,这样文章会更有连贯性。但关于异步的问题不断出现,我决定写一篇关于异步的文章总比没有这一系列文章要好。这就是我现在发表这篇文章的原因。希望我能尽快抽出时间写线程和通信方面的文章。

本文由作者按照 CC BY 4.0 进行授权