多线程:事件循环与线程池等等……
😩 每当我们考虑运行程序时,我们总是专注于运行代码,但我们并不关心谁在运行代码。
您知道谁运行代码、谁将程序传送到 RAM 以及程序如何执行吗?
😎 所以,有个东西叫线程。它负责使用主内存 (RAM)、CPU 和存储,或者说我们机器的一般资源来运行你的程序/代码。
线程只不过是具有线程块、堆栈和堆访问权限的工作者。
但是栈、堆和线程块到底是什么呢?
📌 栈、堆、线程块
- 每当你编写一个函数“PYTHON
def add(a,b):
返回 a + b
Then, when we'll run this code we will declare the function in our main memory (RAM) and a pointer to this function will be stored in the stack.

Img Ref:- [Link](https://www.alexhyett.com/stack-vs-heap-memory/)
✨ So, stack is a scope level memory space where your variables like a and b (Local variables) will be stored and heap is a dynamic memory where the pointers, dynamic arrays and objects (instances of classes) gets stored.
📌 Stack gets cleared when a function's executions gets completed like it will be flushed but heap requires a manual cleaning in some programming languages and in some we have garbage collection.

**Don't worry, follow along you'll get for sure, and please like and save the article to support us**
😎 Now, we know stack, heap which is used to store on the go things when your program runs.
But what about our man who carries whole stuff?? Thread right.
So, thread has thread block

So, thread block has some fields and a kind of storage unit only which has some info to run a program and access some shared space or its own space. Shared space is heap memory space and its own space is stack.
-------
💀 Now, comes the part what is an Event Loop and Thread pool.
When someone works in Javascript he/she might have known that JavaScript is a single threaded language which simply means is that whatever your code is it will be carried by a single worker.
But if someone is working in Java, C, C++ etc there we have multiple threads that can be used in parallel.

Have some patience guys, you will understand 💯
## 📌 Multithreading
Now, let's say you have two functions (in JAVA)
```JAVA
class Main{
public void static main(String[] args){
System.out.println("Hello world");
}
public static void add(int a, int b){
System.out.println(a+b);
}
public static void substract(int a, int b){
System.out.println(a-b);
}
}
😎 现在,线程 1 可以运行 add() 函数并开始执行,线程 2 也可以运行 substract() 函数并开始执行,对吗?因为两者是独立的。
所以,有一种叫做上下文切换的东西。比如说,如果线程 1 正在等待某个用户的输入,那么线程 2 就会运行,上下文就会从线程 1 转移到线程 2。
😎 线程 1 的当前状态将存储在其块中,线程 2 将继续运行。多线程的主要目的是确保 CPU 不会处于空闲状态。它应该持续处于使用状态。
😩 但是在 Javascript 中我们只有线程 1,我们如何在那里并行化事物。
🫶 这里我们有事件循环。
📌 事件循环与线程池
现在假设 JS 中的代码如下:-
function add(){
setTimeout(()->{
console.log("I am lazy");
}, 1000);
console.log("I am active");
}
这里我们可以看到,有一个块正在等待 1000 毫秒(1 秒),之后才会运行。但还有其他独立的代码行可以同时运行。所以,
setTimeout(()->{
console.log("I am lazy");
}, 1000);
可以进入等待阶段,同时
console.log("I am active");
可以运行。所以,setTimeout() 会进入 eventLoop,等待同步代码运行。而这段等待的代码就是异步代码。
图片参考:-链接
❤️ 此时,事件循环会持续循环,检查回调队列中是否有任何要运行的程序(异步代码将进入此队列)。所有同步代码完成后(同步代码堆栈为空),异步代码将运行。
😩 这算是一种阻塞操作吧?如果同步代码陷入无限循环,所有异步代码都会停止,对吧?没错。这就是问题所在,所以超时需要仔细配置。
现在,我们来谈谈线程池:
🥹现在的问题是,当我们读取一个大文件并使其异步时,如果异步代码也应该在将来运行,那么其他同步代码将如何运行。
这里就是线程池。比如,要读取文件,你可以这样做
let filePath = "test.txt";
let fileContent = fs.readFile(filePath, "utf-8", (data, err)->{
return data;
})
现在,我们的操作系统有线程,并且 Javascript 会将读取文件的工作交给操作系统线程池中的一个线程,并且我们的操作系统有一些系统调用,它将使用这些系统调用来读取文件并将其保存到缓冲区。
该缓冲区将仅位于内存中
byte[] buff;
并且有一个回调函数
(data, err)->{
return data;
}
文件读取完成后将调用该方法。然后 Javascript 主线程将内容从 buff[] 复制到数据
因此,在 JS 中,一切看起来都是并行的,但事实并非如此。
🔥 今天就到这里。我们学习了
- 线程、堆栈、堆
- 线程块
- 多线程、上下文切换
- 事件循环、线程池
关注更多深度文章🫶
访问我的 YouTube 频道了解更多信息:链接[语言:印地语,印度🇮🇳]
文章来源:https://dev.to/ssd/multithreading-event-loops-vs-thread-pools-and-more-48di