迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章
原创同步/异步/阻塞/非阻塞/BIO/NIO/AIO:深入解析这些并发编程概念
在计算机科学中,特别是在网络编程和并发编程领域,懂得同步、异步、阻塞、非阻塞、BIO、NIO和AIO等概念至关重要。这些概念涉及到程序怎样处理I/O操作,以及它们怎样影响程序的响应性和性能。本文将深入解析这些概念,帮助读者更好地懂得它们之间的区别和联系。
1. 同步与异步
同步(Synchronous)和异步(Asynchronous)是描述程序执行顺序的两个基本概念。
同步 指的是多个操作或函数调用必须按照某种顺序执行。当一个函数调用另一个函数时,调用者会等待被调用函数执行完成并返回因此。在同步编程中,程序的执行是线性的,一步一步地执行,直到完成。
// 同步示例
def sync_function():
# 执行一些操作
pass
def main():
sync_function()
# 继续执行其他操作
pass
main()
异步 指的是操作可以自立于其他操作执行,并且不需要等待其他操作完成。在异步编程中,程序可以同时执行多个操作,而不需要等待某个操作完成。
// 异步示例
def async_function():
# 执行一些操作
pass
def main():
async_function()
# 不需要等待async_function完成,可以继续执行其他操作
pass
main()
2. 阻塞与非阻塞
阻塞(Blocking)和非阻塞(Non-blocking)是描述程序在等待I/O操作完成时的行为。
阻塞 指的是程序在等待I/O操作完成时会暂停执行,直到操作完成。在阻塞I/O中,线程会被挂起,无法执行其他任务。
// 阻塞I/O示例
import time
def blocking_io():
# 假设这是一个需要等待I/O操作完成的函数
time.sleep(2) # 模拟I/O操作
def main():
blocking_io()
# 在此期间,程序会暂停执行
main()
非阻塞 指的是程序在等待I/O操作完成时不会暂停执行,而是继续执行其他任务。在非阻塞I/O中,线程可以在等待I/O操作时处理其他任务。
// 非阻塞I/O示例
import time
def non_blocking_io():
# 假设这是一个非阻塞I/O操作
pass
def main():
non_blocking_io()
# 程序可以继续执行其他任务,而不是等待I/O操作完成
main()
3. BIO、NIO与AIO
BIO(Blocking I/O)、NIO(Non-blocking I/O)和AIO(Asynchronous I/O)是处理I/O操作的不同方法。
BIO 是最易懂的I/O模型,它使用阻塞方法进行I/O操作。在BIO中,线程在等待I/O操作完成时会阻塞,直到操作完成。
// BIO示例
import socket
def bio_socket():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 9999))
# 执行读写操作
s.close()
bio_socket()
NIO 是Java提供的一种非阻塞I/O模型,它使用Java NIO包中的类和方法。在NIO中,可以使用选择器(Selector)来同时监听多个通道上的事件,从而尽或许减少损耗I/O高效。
// NIO示例
import Java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.ByteBuffer;
public class NIOExample {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
// 处理事件
}
}
AIO 是异步I/O,它允许程序在等待I/O操作完成时执行其他任务。在AIO中,操作系统会负责处理I/O操作,并且当操作完成时,操作系统会通知应用程序。
// AIO示例(使用Java NIO)
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AIOExample {
public static void main(String[]