This article brings you knowledge about our JavaScript single-threading. JavaScript is a single-threaded language. Why can JavaScript execute timers and functions at the same time? I hope it will be helpful to everyone.
1. Process and thread
1.1 Process
is a running activity of a program in the computer on a certain data set. It is the basic unit of resource allocation and scheduling in the system and the basis of the operating system structure. In contemporary computer architecture designed for threads, processes are containers for threads. A program is a description of instructions, data and their organization, and a process is the entity of the program. It is a running activity of a program in a computer on a certain data set. It is the basic unit of resource allocation and scheduling in the system and the basis of the operating system structure. A program is a description of instructions, data and their organization, and a process is the entity of the program.
We compare the process here to the factory floor, which represents a single task that the CPU can handle. At any time, the CPU is always running one process, and other processes are in a non-running state.
1.2 Thread (thread)
is the smallest unit that the operating system can perform operation scheduling. It is included in the process and is the actual operating unit in the process. A thread refers to a single sequential control flow in a process. Multiple threads can run concurrently in a process, and each thread performs different tasks in parallel.
Here, the thread is compared to a worker in a workshop, that is, a workshop can allow multiple workers to collaborate to complete a task.
2. Multi-threaded browser
The browser kernel is multi-threaded. Under the control of the kernel, each thread cooperates with each other to maintain synchronization. A browser usually consists of the following Resident thread composition:
GUI rendering thread
JavaScript engine thread
Event trigger thread
Timed trigger thread
Asynchronous http request thread
We saw the JS engine thread, which is very familiar and correct. This is where we execute the javascript script program.
The JS engine is multi-threaded. Single-threading means that the JS engine only allocates one thread for execution when it executes JS. It means that the JS engine allocates a thread for JavaScript execution, which is what we call Single threaded.
2.1 Let’s talk about the execution mechanism of JS here
Because JavaScript is single-threaded (there is only one JS thread running the JavaScript program in a Tab page at any time) .
So we need to rely on the task queue to execute JavaScript code.
The JS engine will always wait for the arrival of tasks in the task queue, and then execute the tasks.
Of course there is no problem in executing synchronization tasks in this way. We put the tasks in the task queue and execute them one by one. The logic is very clear. However, if we send a request to the background, the time between sending and receiving may take one second. We can't wait for it for one second. If we request five times, then wait for five seconds? The display does not meet our needs, so we need an asynchronous task to handle this problem.
2.2 Synchronous tasks and asynchronous tasks
Synchronous tasks refer to tasks queued for execution on the main thread. Only when the previous task is completed can the next task be continued. , when we open the website, the rendering process of the website, such as the rendering of elements, is actually a synchronous task
Asynchronous tasks refer to tasks that do not enter the main thread but enter the task queue. Only the task queue notifies the main thread , only when an asynchronous task can be executed will the task enter the main thread. When we open the website, loading of pictures and music is actually an asynchronous task.
Everyone must have a relatively concrete understanding of Event Loop. I won’t go into details here. If you don’t understand, you can tell me and I will explain it later.
3. This article focuses on the key points - you can read it directly
But, do you have any questions about the task queue? Is this an object? Is it an array? According to my logic, our JavaScript main thread executes synchronous functions, and asynchronous functions can be placed in the task queue. This task queue can be an object. When we finish executing the synchronous task, push this object (task queue) into the main thread. It's fine in the thread, but it's not what I thought.
The task queue of Evnet Loop is placed in the event triggering thread of the browser. When the JS engine executes an asynchronous function, the asynchronous task will be placed in the event triggering thread. When the corresponding asynchronous task meets the triggering conditions When triggered, the event triggering thread will add the asynchronous task to the end of the queue of the main thread in the JS engine, waiting for execution.
Is it different from the single-threaded JavaScript we imagined? Well, it's really not the same, so the final conclusion is that the task queue we are talking about is actually a thread.
Then, going back to the timer we mentioned at the beginning, everyone can basically guess it. It is controlled by the timer thread.
Because JavaScript is single-threaded, if it is in a blocked thread state, it will affect the accuracy of timing, so it is necessary to open a separate thread for timing.
When using setTimeout or setInterval, it requires the timer thread to time, and after the time is completed, the specific event will be pushed into the event queue.
4. Conclusion
So, we are right to say that JavaScript is single-threaded. Even if the king comes, it is also single-threaded, but our Event Loop and timers are placed in other threads.
5. V8 engine - extension
The V8 engine is a JavaScript engine implementation. It was originally designed by some language experts and was later acquired by Google. Open sourced.
V8 is developed using C. Before running JavaScript, compared to other JavaScript engines that convert it into bytecode or interpret it for execution, V8 compiles it into native machine code (IA-32, x86-64, ARM , or MIPS CPUs), and uses methods such as inline caching to improve performance.
With these features, JavaScript programs run as fast as binary programs under the V8 engine. V8 supports many operating systems, such as windows, linux, android, etc., and also supports other hardware architectures, such as IA32, X64, ARM, etc., and has good portability and cross-platform features.
5.1 Workflow
The V8 engine has two main stages in the process of executing JavaScript: compilation and running, which is different from C's complete compilation before execution. , JavaScript needs to be compiled and executed when the user uses it. In V8, JavaScript-related code is not compiled all at once, but is compiled when certain codes need to be executed, which improves response time and reduces time overhead. In the V8 engine, the source code is first converted into an abstract syntax tree (AST) by the parser, and then the full code generator of the JIT compiler is used to directly generate local executable code from the AST. This process is different from JAVA's first generation of bytecode or intermediate representation, which reduces the conversion time from AST to bytecode and improves the code execution speed. However, due to the lack of the intermediate process of conversion to bytecode, the opportunity to optimize the code is reduced.
The main classes used by the V8 engine when compiling local code are as follows:
Script: represents JavaScript code, including source code and local code generated after compilation Code is both the compilation entrance and the running entrance;
Compiler: Compiler class, auxiliary group Script class to compile and generate code, call the interpreter (Parser) to generate AST and full Code generator, converts AST into local code;
AstNode: Abstract syntax tree node class, which is the base class for all other nodes, contains many subclasses, which will be discussed later for different Subclasses generate different local codes;
AstVisitor: Visitor class of abstract syntax tree, mainly used to traverse heterogeneous abstract syntax trees;
FullCodeGenerator: A subclass of the AstVisitor class that generates local executable code for JavaScript by traversing the AST.
The process of JavaScript code compilation is roughly as follows: the Script class calls the Compile function of the Compiler class to generate local code for it. The Compile function first uses the Parser class to generate AST, and then uses the FullCodeGenerator class to generate local code. Native code is closely related to the specific hardware platform, and FullCodeGenerator uses multiple backends to generate native assembly code that matches the platform. Since FullCodeGenerator generates corresponding assembly code for each node by traversing the AST, the global view is missing, and optimization between nodes is out of the question
[Related recommendations: javascript learning tutorial 】
The above is the detailed content of Do you really understand JavaScript's single thread?. For more information, please follow other related articles on the PHP Chinese website!