A synchronous call waits for its operation to complete before the caller proceeds. In a synchronous processing sequence, the next task does not start until the current one finishes. This is straightforward to follow, but a slow or blocked operation delays the work behind it. section 10.1.1
One request at a time
A single-threaded server receives a message, parses it, obtains the requested information, formats a response, and sends it before handling another request. Receiving may block until the message arrives; slow request processing holds up the next request. section 10.1.1
Synchronous calls do not rule out concurrency across threads. One thread can block in a socket call while the operating system runs another. An asynchronous server instead uses interfaces such as I/O multiplexing to find ready sockets and make progress on other requests without waiting on the same thread. That distinction matters when the aim is to hide I/O latency rather than shorten the I/O itself. section 10.1.1 section 10.1
Figure 10.1 Synchronous versus asynchronous processing. Synchronous processing (at the top) processes sequentially from one task to the next. In this example, we have tasks A and B, where A submits I/O. The I/O is executed synchronously before task B can execute. In contrast, asynchronous processing (at the bottom) can perform I/O in parallel with task B. That is, task A runs, submits the I/O, and immediately starts executing task B. When the I/O for task A and task B finishes, we’re done, completing the work faster than with synchronous processing.
The timelines show the cost of waiting: synchronous I/O finishes before the next task starts, while asynchronous I/O can overlap that task. section 10.1.1
Listing 10.1 A simple example of a synchronous system
fn process_requests(socket: &Socket) {
loop {
process_request(socket);
}
}
fn process_request(socket: &Socket) {
let msg = socket.recv();
let request = parse_message(msg);
let resp = match request {
Request::GetUserInfo(id) => get_user_info(id);
};
let resp = format_response(resp);
socket.send(resp);
}
The request loop makes the sequencing concrete: receive, parse, process, and send all finish before the next iteration. section 10.1.1





