paint-brush
进程和线程:掌握 Linux 的基础经过@infinity
4,319 讀數
4,319 讀數

进程和线程:掌握 Linux 的基础

经过 Rishabh Agarwal7m2022/08/22
Read on Terminal Reader
Read this story w/o Javascript

太長; 讀書

摩尔定律从来都不是法律,而是一种观察。摩尔定律观察到,密集集成电路中的晶体管数量每两年翻一番。在 Linux 中,所有这些东西的集合称为一个进程。 Linux 建立在进程的基础之上。要检查您机器上运行的不同进程,您可以尝试运行以下命令:bash。这将运行所有进程及其进程 ID 以及进程 ID。 Linux 系统中的每个进程都会有一个唯一的命令来识别它使用的是哪个。

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - 进程和线程:掌握 Linux 的基础
Rishabh Agarwal HackerNoon profile picture



您是否听说过支配半导体行业近 60 年的摩尔定律?你知道摩尔定律从来都不是法律,而是一种观察?对于那些不熟悉这条法律的人来说,这就是它的表达方式。


摩尔定律观察到,密集集成电路中的晶体管数量每两年翻一番。


虽然这条规则是用电子学来写的,但从计算机的角度来看,它表明计算能力每两年翻一番。本质上,单个芯片上的计算能力呈指数级增长。是不是很棒?


令人惊奇的是,自从有了这个观察,它就被证明是正确的,现在被视为一种规则。


资料来源:维基百科


然而,众所周知,美好的事物并不总是免费的。在这种情况下,更强大的计算是以过度加热为代价的。当他们在 2010 年到达时,加工商达到了足以烹饪意大利面的温度。 (查看youtube 视频以亲自体验)。


此外,随着芯片上晶体管数量的增加,开始达到材料的物理极限。此时亚原子力开始变得活跃,这使得维持摩尔定律轨迹变得具有挑战性。


感觉就像计算机变得越来越快的美好时光已经结束。但工程师有其他计划。他们开始使用多个强大的核心,而不是单个超级强大的核心。


尽管它可能已经解决了硬件问题,但它给软件工程师带来了新的挑战。工程师必须开发利用计算机现在拥有的几个内核的软件。因此,通常称为并行编程的并发编程应运而生。线程是这个编程领域的焦点。但在谈论线程之前,我们必须了解什么是进程。


什么是 Linux 进程?

Linux 进程被定义为程序的运行实例。


因此,系统必须在执行程序时跟踪许多项目,包括堆栈内存、源代码和寄存器等。在 Linux 中,所有这些东西的集合称为一个进程。 Linux 建立在进程的基础之上。


要检查您机器上运行的不同进程,您可以尝试运行以下命令。这将运行所有进程及其进程 ID。


 $ ps


这是一个示例快照。




默认情况下,上面的命令只显示与当前用户关联的那些进程。要列出所有进程,我们可以使用带有以下选项的命令。


 $ ps -aux


这是一个示例快照。


将这些额外的选项应用到ps命令也为我们提供了一些额外的信息。这是不同标志的含义-


  1. a代表所有用户
  2. u代表当前用户
  3. x显示在终端外执行的进程


我们还可以使用kill命令杀死一些进程。这是它的使用方法 -


 $ kill PID


这里的PID是我们可以从ps命令中获取的进程 ID。 Linux 系统中的每个进程都会有一个唯一的PID ,用于识别它。您甚至可以使用命令pidof来查找进程的PID


 $ pidof bash


进程中的父子关系

当您启动程序或发出命令时,就会形成一个进程。当您从终端执行命令时,您将启动一个新进程。因为使用终端来生成这个新进程,所以我们说终端进程启动了新的命令进程。换句话说,新的命令进程是终端进程的子进程。


Linux 生态系统中的每个进程都有一个创建它的父进程。我们可以使用以下命令来检查具有给定PID的进程的父进程。


 $ ps -o ppid= -p PID


Linux 中的所有进程都直接或间接地是 PID 为 1 的进程的子进程。这并非巧合。 PID 为 1 的进程是 init 进程,是系统在启动时启动的第一个进程。任何后续进程都被创建为此进程的子进程。


因此,我们有一个由进程之间的这些关系构成的树。这称为进程树。


流程很重🪨

进程在 Linux 中非常有用,没有它们我们就活不下去。但是它们有一个缺点,或者可能根本不是缺点,而只是它们的运作方式。手续繁重。每当启动新进程时,都会传输数据、内存和变量。运行相同程序的每个进程都将拥有自己的源代码副本。因此,产生大量进程并不是一个聪明的主意。


然而,由于进程是一种同时服务多个请求的机制,我们被这个令人不快的事实所束缚。我们只能为少数有很多共同点的并发用户提供服务,因为我们只能在系统中启动有限数量的进程。考虑一个必须为众多并发用户提供服务的 Web 服务器。为每个用户创建一个新进程是一项昂贵的操作。因此,我们想要比手术更便宜的东西。线程在这里发挥作用。


什么是线程? 🧵

线程只是轻量级进程。线程与其父进程和它创建的任何线程共享内存。由于这种共享内存,产生新线程的成本较低。这提供了更快的线程通信和上下文切换的额外好处。使用线程,一个进程可以同时执行多个任务。


与进程数相比,我们可以生成大量线程。在多核机器上,这些线程是并行执行的。与生成许多进程或按顺序执行所有任务相反,这提高了程序的整体性能。


让我们尝试开始我们的第一个线程。需要注意的是,我们不能用 bash 启动新线程。 bash 命令只能用于创建子进程。所以,我们要做的是编写一个启动两个线程的 C 代码。然后,使用 bash,我们将这个 C 代码作为子进程执行。然后,这个新进程将创建两个线程。


在 C 中创建线程

让我们开始着手编写一些代码。创建一个新文件并将其命名为threads.c 。继续并在您最喜欢的任何 IDE 中打开它。


第一步是导入所需的头文件。


 #include <pthread.h> #include <stdio.h>


我们将创建两个线程,每个线程执行相同的函数但参数不同。让我们编写那个函数。


 void* print_multiple_messages(void* ptr) { char* message = (char*) ptr; for(int i=0; i<1000; ++i) { printf("%s \n", message); } }


正如你所看到的,这个函数没有什么大不了的。它将消息作为输入参数并打印一千次。


现在让我们编写 main 函数。


 int main() { // Continue writing from here }


就像进程一样,线程也有用于唯一标识它们的 ID。创建两个变量来保存这些 ID。


 pthread_t thread1, thread2;


我们将为每个线程使用不同的消息。创建两个字符串(字符数组)来保存不同的消息。


 char* message1 = "Thread 1"; char* message2 = "Thread 2";


下一步是创建两个线程。我们将使用pthread_create方法来做到这一点。


 pthread_create(&thread1, NULL, print_multiple_messages, (void*) message1); pthread_create(&thread2, NULL, print_multiple_messages, (void*) message2);


这将启动两个新线程。让我们指示我们的主进程等到两个线程完成它们的工作。


 pthread_join(thread1, NULL); pthread_join(thread2, NULL);


就是这样。编译代码并执行它。您会注意到来自两个线程的消息会混淆。这表明它们是并行执行的。


恭喜你刚刚创建了你的第一个线程。



因此,在本文中,我们讨论了线程和进程。这些是 Linux 最引人入胜的一些特性,掌握它们至关重要。它支持硬件感知软件的开发和有效利用我们可支配的资源。


在这里,我们将对这篇文章做一个总结。我们努力提供足够的细节来让您继续前进,但事实并非如此。所以继续学习更多。如果您喜欢这些内容,您可能想发表评论和/或表达情感。


享受学习!