During application development, we often confront terms like "Blocking," "Non-blocking," "Synchronous," and "Asynchronous." It's a common misconception to view these as synonymous. In reality, they represent distinct, albeit intertwined, concepts.
One frequent point of confusion is between "Blocking" and "Synchronous" and between "Non-blocking" and "Asynchronous."
In essence:
Let's delve into these concepts in more detail.
The crux of this distinction lies in how a system responds when waiting for another process.
When considering multiple subjects executing tasks:
When an I/O function is invoked:
In terms of who oversees task completion for the I/O function:
Based on the combinations of Blocking/Non-Blocking and Synchronous/Asynchronous, the four resulting quadrants are shown in the diagram below:
This is the most straightforward method of I/O. When you make a call, the program waits for the operation to complete before moving on.
#include <iostream>
#include <fstream>
int main() {
std::ifstream file("example.txt");
std::string content;
// This line blocks until the entire file is read
std::getline(file, content, '\0');
std::cout << content;
file.close();
return 0;
}
In this mode, the system would regularly check (or poll) if data is available. If not, it would continue doing something else.
// This is a simplified example. True non-blocking I/O in C++ can be complex.
// Assuming a non-blocking I/O library function 'try_read'
/*
bool try_read(std::ifstream& file, std::string& content);
*/
int main() {
std::ifstream file("example.txt");
std::string content;
while (!try_read(file, content)) {
// Do other tasks or sleep for a while
}
std::cout << content;
file.close();
return 0;
}
This sounds contradictory, but it can be thought of as starting an I/O operation asynchronously, but once started, that particular I/O operation would block until completion. This is often used with I/O multiplexing.
// An example using pseudo-code, as actual implementations vary.
// Assuming a function 'async_read' that starts reading and blocks until it completes.
/*
void async_read(std::ifstream& file, void (*callback)(std::string content));
*/
void print_content(std::string content) {
std::cout << content;
}
int main() {
std::ifstream file("example.txt");
async_read(file, print_content);
// Do other tasks while I/O is ongoing
file.close();
return 0;
}
In this mode, the I/O operation starts and the control returns immediately, allowing the program to continue executing subsequent statements without waiting.
// Assuming a library function 'async_read_nonblocking'
/*
void async_read_nonblocking(std::ifstream& file, void (*callback)(std::string content));
*/
void print_content(std::string content) {
std::cout << content;
}
int main() {
std::ifstream file("example.txt");
async_read_nonblocking(file, print_content);
// Do other tasks immediately without waiting for the I/O to complete
// Wait or poll for the asynchronous I/O to complete if needed
file.close();
return 0;
}
These concepts revolve around how applications and kernels interact. Distinguishing between them requires understanding the difference between the application and kernel domains. Reviewing the explanations, associated diagrams, and code examples above can provide a clearer picture.
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有