NodeJs 第二十七章 进程和线程

本文详细阐述了进程和线程在计算机中的概念,强调了进程的独立性和资源管理,以及线程的并发性与数据共享。特别关注Node.js如何利用单线程和非阻塞I/O实现高效的异步编程,以提升系统性能和并发处理能力。
摘要由CSDN通过智能技术生成

进程

进程是计算机运行程序的实例,它是操作系统对一个正在运行中的程序的抽象。每个进程都有自己的地址空间,包括代码、数据、堆栈等,以及运行时所需的资源,如打开的文件、设备等。进程是操作系统进行资源分配和调度的基本单位,它可以独立运行、中断和恢复。

一个应用程序,总是通过操作系统启动的,当操作系统启动一个应用程序时,会给其分配一个进程

一个进程拥有独立的、可伸缩的内存空间,原则上不受其他进程干扰。

进程之间是可以通信的,只要两个进程双方遵守一定的协议,比如ipc

CPU在不同的进程之间切换执行

虽然一个应用程序在启动时只有一个进程,但它在运行的过程中,可以开启新的进程,进程之间仍然保持相对独立

如果一个进程是直接由操作系统开启,则它叫做主进程

如果一个进程B是由进程A开启,则A是B的父进程,B是A的子进程,子进程会继承父进程的一些信息,但仍然保持相对独立

// nodejs 中开启子进程
const childProcess = require("child_process"); // 导入内置模块

childProcess.exec(在子进程运行的命令, (err, out, stdErr) => {
  // 回调函数中可以获取子进程的标准输出,这种数据交互是通过IPC完成的,nodejs已经帮你完成了处理
  // err:开启进程过程中发生的错误
  // out: 子进程输出的正常内容
  // stdErr: 子进程输出的错误内容
  // 子进程发生任何的错误,绝不会影响到父进程,它们的内存空间是完全隔离的
});

// 过去,nodejs没有提供给用户创建线程的接口,只能使用进程的方式
// 过去,nodejs还提供了cluster模块,通过另一种模式来创建进程
// 现在,nodejs已经提供了线程模块,对进程的操作已经很少使用了

线程

线程是计算机科学中的基本概念,是进程中的执行单元。一个进程可以包含多个线程,每个线程可以独立执行不同的任务。线程是操作系统调度的最小单元,它拥有自己的程序计数器、堆栈和一组寄存器。不同的线程之间可以共享同一进程的资源,如内存空间和文件句柄。线程可以同时执行多个任务,提高程序的并发性和响应能力。常见的线程模型有用户级线程和内核级线程。

操作系统启动一个进程(无论是主进程,还是子进程),都会自动为它分配一个线程,称之为主线程

程序一定在线程上运行!!

主线程在运行的过程中,可以创建多个线程,这些线程称之为子线程

当操作系统命令CPU去执行一个进程时,实际上,是在该进程的多个线程中切换执行

线程和进程很相似,它们都是独立运行,最大的区别在于:线程的内存空间没有隔离,共享进程的内存空间,线程之间的数据不用遵守任何协议,可以随意使用

什么时候要使用线程?

使用线程的主要目的,是为了充分使用多核cpu。线程执行过程中,尽量的不要阻塞。

最理想的线程效果:

  1. 线程数等于cpu的核数
  2. 线程永不阻塞
    1. 没有io
    2. 只存在大量运算
  3. 线程相对独立,几乎不使用共享数据

线程一般处理cpu密集型操作(运算操作),而io密集型操作不适合使用线程,而适合使用异步

为了避免线程执行过程中共享数据产生的麻烦,nodejs使用独特的线程机制来尽力规避:

// 创建子线程的父线程
const { Worker } = require("worker_threads");
const worker = new Worker(线程执行的入口文件, {
  workerData: 开启线程时向其传递的数据,
}); // worker是子线程实例

// 通过EventEmitter监听子线程的事件
worker.on("exit", () => {
  // 当子线程退出时运行的事件
});
worker.on("message", (msg) => {
  // 收到子线程发送的消息时运行的事件
});
worker.postMessage(任意消息); // 父线程向子线程发送任意消息
worker.terminate(); // 退出子线程
const {
  isMainThread, // 是否是主线程
  parentPort, // 用于与父线程通信的端口
  workerData, // 获取线程启动时传递的数据
  threadId, // 获取线程的唯一编号
} = require("worker_threads");

parentPort.on("message", (msg) => {
  // 当收到父线程发送的消息时,触发的事件
});
parentPort.postMessage(workerData); // 向父线程发送消息

Nodejs 线程机制

Node.js 实际上是基于单线程的事件驱动模型进行开发的,这是因为 JavaScript 语言本身是单线程的。但是,Node.js 通过使用事件循环和非阻塞 I/O 模型实现了异步操作,从而能够处理大量的并发请求。

Node.js的线程机制包括以下几个部分:

  1. 事件循环(Event Loop):Node.js中的事件循环采用了Libuv库来实现,它负责管理和调度事件以及回调函数的执行。事件循环的核心思想是将事件和回调函数放入事件队列中,然后在适当的时候调用回调函数来处理事件。

  2. 单线程:Node.js中只使用了一个线程来处理所有的请求。这个线程会不断地处理事件和回调函数,而不阻塞其他请求的处理。这样可以提高系统的吞吐量和并发性能。

  3. 非阻塞I/O:Node.js采用非阻塞的I/O模型,也就是说在进行I/O操作时不会阻塞其他的操作。当有一个I/O操作需要进行时,Node.js会将该操作交给操作系统处理,并立即返回一个回调函数,然后继续处理其他请求。当操作系统完成I/O操作后,会将结果返回给Node.js,并通过事件队列中的回调函数来处理。

  4. 异步编程:Node.js鼓励使用异步编程的方式来处理请求,以便提高系统的性能和响应速度。通过使用回调函数、Promise、Async/Await等方式,开发者可以在不阻塞主线程的情况下处理大量的并发请求。

Node.js 的核心机制是事件循环,它是实现异步操作的基础。事件循环是一个不断循环的过程,它会检查事件队列中是否有待处理的事件,如果有则执行相应的回调函数。这种机制可以实现非阻塞的 I/O 操作,当有新的 I/O 请求时,不需要等待结果返回,而是直接进行下一个事件的处理。

总结来说,Node.js使用单线程的事件循环机制和非阻塞I/O模型来实现高性能的异步编程。这种机制能够更好地利用系统资源,提高系统的吞吐量和并发性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值