Primitives for Distributed Communication
Blocking/Non-blocking, Synchronous/Asynchronous Primitives
Communication in distributed systems uses two basic primitives: Send() and Receive().
-
Send() has two parameters:
- destination (process where data is sent)
- buffer (user space data to be sent)
-
Receive() has two parameters:
- source (from where data is received; can be a wildcard)
- buffer (user buffer to store received data)
There are two Send options:
- Buffered option – data is copied from user buffer → kernel buffer → network.
- Unbuffered option – data is copied directly from user buffer → network.
For Receive, buffering is usually required because data may already arrive before primitive is invoked, so kernel buffer is needed.
Synchronous and Asynchronous Primitives
-
Synchronous primitives:
- Send() completes only after corresponding Receive() is invoked and completed.
- Receive() completes when data is copied into receiver’s buffer.
-
Asynchronous primitives:
- Send() is asynchronous if control returns after copying data out of the user buffer.
- Asynchronous Receive() is not meaningful.
Blocking and Non-blocking Primitives
-
Blocking primitive: Control returns only after the primitive completes (synchronous or asynchronous).
-
Non-blocking primitive: Control returns immediately after invocation, even if operation is not completed.
- Non-blocking Send: returns before data is copied out of user buffer.
- Non-blocking Receive: returns before data has arrived.
Handling Non-blocking Operations
For non-blocking Send, code works in two ways:
- Keep checking if handle is flagged/posted.
- Use Wait() with a list of handles.
- Wait() blocks until one handle is posted.
- If operation already completed, Wait() returns immediately.
- When operation completes, communication subsystem sets handle and wakes up waiting process (posting completion).
Versions of Send and Receive Primitives
-
Send primitive has 4 versions:
- Synchronous blocking
- Synchronous non-blocking
- Asynchronous blocking
- Asynchronous non-blocking
-
Receive primitive has 2 versions:
- Blocking synchronous
- Non-blocking synchronous
Timing diagrams show process execution, user buffer, and kernel/communication subsystem for each version:
- Blocking synchronous Send, blocking Receive
- Non-blocking synchronous Send, non-blocking Receive
- Blocking asynchronous Send
- Non-blocking asynchronous Send
v2

