Синхронные, асинхронные, блокирующие, не блокирующие, эти четыре концепции очень мало людей могут четко сказать, не верьте в это, вы можете сначала попытаться записать
синхронный и асинхронный
关注维度:消息的通信机制(synchronous communication/asynchronous communication)
判断标准:调用者是否主动等待被调用者的返回结果
同步的理论说明:任务A的执行过程中调用了任务B。任务A对任务B发起调用后,主动等待调用结果。
同步的生活举例:你去书店问老板,是否有《操作系统》这本书,老板说:稍等,我查一下。然后开始查啊查,等查好了,告诉你结果(主动等待被调用方返回结果)。
异步的理论说明:任务A的执行过程中调用了任务B。任务A对任务B发起调用后,继续执行后续工作。任务B完成后通过状态、通知来通知调用者。
异步的生活举例:你去书店问老板,是否有《操作系统》这本书,查好了打电话给你,然后直接挂电话了(此时被调用方不返回结果)。过了几天,查好了,老板主动打电话给你(被调用方回调调用方,告知结果)。
блокирующий и неблокирующий
关注维度:任务在等待调用结果时的状态
判断标准:调用方在等待被调用方的返回结果时,是否可以做其他事(是否被挂起)
阻塞的理论说明:任务A对任务B发起调用后,任务B需要执行一段时间才可返回结果,任务A选择等待任务B的返回结果(暂时挂起)。
阻塞的生活举例:你去书店问老板,是否有《操作系统》这本书,你会一直把自己挂起,什么是后不干,一直在那等,直到得到返回结果。
非阻塞的理论说明:任务A对任务B发起调用后,与此同时,任务A在任务B执行的过程中去完成别的工作,等待任务B结果返回后再继续(不挂起,而是继续执行自己的任务)。
非阻塞的生活举例:你去书店问老板,是否有《操作系统》这本书,不管老板有没有告诉你,你自己都先去玩了(继续执行自己的任务而不是干等),但是也要偶尔也要check一下老板是否有了结果。
Мы рассматриваем пользовательский поток как вызывающую программу, а поток ядра — как вызываемую и описываем несколько моделей ввода-вывода текущего процесса с помощью нескольких изображений и простых примеров кода:
Синхронный блокирующий ввод-вывод:
read(socket, buffer)
process(buffer)
Синхронный неблокирующий ввод-вывод:
while(read(socket,buffer) != SUCCESS);
process(buffer);
Мультиплексирование ввода-вывода:
select(socket);
while(1){
sockets = select();
for(socket in sockets){
if(canRead(socket)){
read(socket,buffer);
process(buffer);
}
}
}
Хотя этот метод позволяет обрабатывать несколько запросов ввода-вывода в одном потоке, процесс каждого запроса ввода-вывода по-прежнему блокируется, а среднее время даже больше, чем в модели синхронного блокирующего ввода-вывода.
Реакторный режим:
UserEventHandler handleEvent(){
if(canRead(socket)){
read(socket,buffer);
process(buffer);
}
}
Reactor.register(new UserEventHandler(socket));
Reactor.epollHandleEvents(){
while(1){
sockets = select();
for(socket in sockets){
getEventHandler(socket).handleEvent();
}
}
}
Мультиплексирование ввода-вывода по-прежнему использует системный вызов select, который блокирует поток.В лучшем случае его можно рассматривать только как асинхронный блокирующий ввод-вывод, а не настоящий асинхронный ввод-вывод.
Асинхронный неблокирующий ввод-вывод:
При асинхронном блокирующем вводе-выводе пользовательский поток считывает и обрабатывает данные самостоятельно после получения уведомления. В асинхронном неблокирующем вводе-выводе, когда пользовательский поток получает уведомление, данные подготовлены, и пользовательский поток может использовать их напрямую (процесс чтения данных опущен)
aioRead(socket, new UserCompeletionHandler());
Что это за процесс:
计算机最初发明的初衷是用于解决耗时耗力的复杂计算,是一个计算器
最原始的计算机执行程序的过程如下:等待用户输入指令->用户输入->计算机操作->等待用户输入指令->用户输入->计算机操作。在用户思考或者输入的过程中,计算机就空闲下来。
后来有了批处理系统,用户可以把许多指令(如输入1,输入2)写在磁盘中,计算机的执行过程变为:用户输入指令集合->取指令->执行->取指令->执行。
批处理系统大大提高了便捷性,但是还是存在一个问题,假设指令集合中有A,B两个程序,当程序A进行I/O处理时,程序B只能等待程序A直到其运行完。也就是说,内存中只能有一个程序在执行。
|程序One|程序Two| 计算机中有两个程序
Time1: |内存| 内存中装载程序One
Time2: |内存| 内存中装载程序Two
那么,如何在内存中装入多个程序呢?于是人们发明了进程,每个在运行的程序都看做一个进程,给每个进程分配合适大小的对应的内存地址空间,进程之间的空间互不干扰,并且保存每个进程的运行状态。通过进程之间的相互切换,使计算机看起来在一段时间内有几个程序在同时执行。
|程序One|程序Two| 计算机中有两个程序
Time1: |部分内存|部分内存| 内存中装载程序One,Two,分别在不同的部分。
进程让程序之间的并发成为了可能,从宏观上看,某个时间段内有多个程序在同时执行,但实际上在某一时刻只有一个程序(一部分的内存)会得到CPU,进行执行。
Что такое нить:
进程让程序之间的并发成为了可能,我们可以在电脑上同时听歌,打字了(两个不同的程序之间切换)。
Но требования людей к производительности программ в реальном времени становятся все выше и выше. Например, для QQ Music нужно не только обрабатывать интерактивные запросы, отправленные пользователями, но и воспроизводить песни. Предполагая, что QQ Music воспроизводит песню в определенный момент, вы нажимаете кнопку «пауза», и вам нужно дождаться окончания песни перед обработкой операции «пауза».
Таким образом, люди разбили процесс, соответствующий программе QQ Music, на несколько потоков. Есть потоки для воспроизведения песен и потоки для обработки интерактивных запросов. Каждый поток отвечает за независимую подзадачу. В данном случае мы нажали кнопку «пауза», QQ Music освобождает поток, который приостанавливает воспроизведение песни, позволяет потоку интерактивного запроса обработать запрос пользователя, а затем переключается обратно после ответа, так что поток, воспроизводящий песню, получает ЦП. Конкретный процесс выглядит следующим образом:
播放线程---------------------挂起`````````````````播放线程----------
用户点击暂停
交互线程--------处理完毕
线程让进程内的子任务并发成为了可能。
3. Программа, процесс, поток:
Программа — это код, который мы пишем, и для запуска он должен соответствовать конкретному процессу.Процессы имеют независимые адреса памяти и не мешают друг другу. Потоки — это подзадачи процесса, а потоки, принадлежащие одному и тому же процессу, совместно используют одну и ту же память.
Процессы делают возможным параллелизм между программами, а потоки делают возможным параллелизм подзадач внутри процесса.