非阻塞
非阻塞,就是当一个任务正在执行的时候,允许程序继续执行其他任务,而不用等待这个任务执行完毕。
Non-blocking refers to the ability of a system, program, or piece of code to continue executing without being halted by certain operations or tasks. This concept is crucial in concurrent and parallel computing, where multiple tasks or threads need to run simultaneously without waiting for each other to complete. Here’s a breakdown of how to comprehend non-blocking:
Basic Definition:
- Blocking: When an operation must wait for a certain condition or event to complete before proceeding, it is considered blocking. For example, reading from a file might block a program until the read operation is complete.
- Non-Blocking: A non-blocking operation allows the program to continue executing other tasks while the operation is still in progress. The program does not wait for the operation to complete before moving on.
Examples in Different Contexts:
- Networking: In network programming, non-blocking I/O allows a program to initiate a network request and then continue doing other work while waiting for the response. This is opposed to blocking I/O, where the program would pause execution until the network request is complete.
- User Interfaces: In graphical user interfaces (GUIs), non-blocking is essential to keep the interface responsive. For example, when a user clicks a button to start a long-running task, a non-blocking implementation would allow the user to continue interacting with the interface while the task runs in the background.
- Multithreading: In concurrent programming, non-blocking algorithms allow multiple threads to operate on shared data without causing the threads to wait for one another. This is often achieved using atomic operations and lock-free data structures(这通常是使用原子操作和无锁数据结构来实现的).
Benefits:
- Responsiveness: Non-blocking operations improve the responsiveness of applications, especially in environments where delays are unacceptable (e.g., real-time systems, user interfaces).
- Efficiency: They can lead to better utilization of system resources, as the system can perform other useful work while waiting for an operation to complete.
Common Techniques:
- Callbacks: A function is passed as an argument and is called once the operation completes.
- Promises/Futures: These represent a value that may be available at some point in the future, allowing the program to continue executing and handle the value when it becomes available.
- Async/Await: Modern programming languages offer async/await syntax to write non-blocking code in a more readable and manageable way.
下面通过一个例子来说明,你一下子就明白了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import asyncio async def non_blocking_task(): print("Task started") await asyncio.sleep(2) # Simulate a non-blocking delay print("Task completed") async def main(): print("Main started") task = asyncio.create_task(non_blocking_task()) print("Main continues to run") await task # Wait for the task to complete print("Main completed") asyncio.run(main()) |
看上面程序,你先不要考虑线程什么的,main 方法里调用了 non_blocking_task()
那么程序就会执行 non_blocking_task()
方法,执行到 await asyncio.sleep(2)
时程序返回,继续执行 main 方法里其他代码,等 await asyncio.sleep(2)
执行完毕,程序在继续执行 print("Task completed")
,这个例子就演示了什么“非阻塞”。
In this example, asyncio.sleep(2)
is a non-blocking sleep operation. The main function continues to run while the task is sleeping, demonstrating non-blocking behavior.
Understanding non-blocking is essential for writing efficient and responsive applications, particularly in environments where tasks need to be performed concurrently.
异步
The terms “non-blocking” and “asynchronous” are closely related but are not synonymous. They both deal with the handling of tasks that may take some time to complete, but they do so in slightly different ways. Here’s a breakdown of their differences and relationship:
Non-Blocking
Definition:
- Non-blocking refers to operations that do not halt the execution of the program while waiting for the operation to complete. The program can continue executing other tasks.
Characteristics:
- The operation returns immediately, even if it hasn’t completed.(操作立刻返回,即使它还没有完成)
- Common in I/O operations, where the program can initiate an operation and immediately proceed without waiting.(通常在 I/O 操作中,程序可以立即开始一个操作而不同等待它完成)
- Often achieved using techniques like callbacks, polling, or event loops.(通常使用回调、池、事件循环实现)
Examples:
- Non-blocking I/O: A program initiates a file read operation and can continue processing other tasks while waiting for the read to complete.
- Non-blocking algorithms in concurrent programming, such as lock-free data structures.
Asynchronous
Definition:
- Asynchronous refers to the execution of tasks in a way that allows them to run independently of the main program flow. Asynchronous operations often use non-blocking mechanisms, but they include additional structures to manage the completion of tasks.(异步指任务的执行允许它们独立执行,异步操作通常使用了“非阻塞”的机制,但它们包含了额外的结构来管理任务的完成)
Characteristics:
- Typically involves a higher level of abstraction than non-blocking.(通常涉及比非阻塞更高级别的抽象。)
- Uses constructs like futures, promises, and async/await to handle the results of operations that will complete at some point in the future.
- Asynchronous programming is often used to handle I/O-bound and high-latency operations efficiently.
Examples:
- Asynchronous I/O: Similar to non-blocking I/O, but uses constructs like async/await to manage the flow.
- Asynchronous functions in programming languages like Python (using
async def
andawait
), JavaScript (usingasync
andawait
), and C#.
Relationship
- Overlap:
- Asynchronous operations are often implemented using non-blocking techniques. For instance, an asynchronous read operation might be non-blocking and use a callback or promise to handle the completion.(异步通常使用了非阻塞的技术)
- Both aim to improve the efficiency and responsiveness of applications by allowing other tasks to run while waiting for an operation to complete.
- Abstraction Level:
- Non-blocking is a lower-level concept focused on immediate return of control to the program.(非阻塞是一个较低级别的概念,侧重于立即将控制权返回给程序)
- Asynchronous programming provides a higher-level abstraction for managing the lifecycle and completion of tasks, often making non-blocking operations easier to work with.(异步编程为管理生命周期和任务的完成提供了更高级别的抽象,通常使非阻塞操作更易于使用)
Example in Python
Here’s how non-blocking and asynchronous concepts can be seen in Python:
Non-Blocking I/O with Callbacks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import socket import selectors sel = selectors.DefaultSelector() def read(conn, mask): data = conn.recv(1000) # Should be ready if data: print('Received', repr(data)) else: print('Closing', conn) sel.unregister(conn) conn.close() sock = socket.socket() sock.connect(('example.com', 80)) sock.setblocking(False) sel.register(sock, selectors.EVENT_READ, read) # Event loop while True: events = sel.select() for key, mask in events: callback = key.data callback(key.fileobj, mask) |
Asynchronous with Asyncio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import asyncio async def fetch_data(): print("Fetching started") await asyncio.sleep(2) # Simulate I/O operation print("Fetching completed") async def main(): print("Main started") await fetch_data() print("Main completed") asyncio.run(main()) |
In the first example, non-blocking I/O is achieved using selectors and callbacks. In the second example, asynchronous programming with asyncio
provides a higher-level abstraction that simplifies the handling of asynchronous tasks.