ipc-channel
is an inter-process implementation of Rust channels (which were inspired by CSP1).
A Rust channel is a unidirectional, FIFO queue of messages which can be used to send messages between threads in a single operating system process. For an excellent introduction to Rust channels, see Using Message Passing to Transfer Data Between Threads in the Rust reference.
ipc-channel
extends Rust channels to support inter-process communication (IPC) in a single operating system instance. The serde
library is used to serialize and deserialize messages sent over ipc-channel
.
As much as possible, ipc-channel
has been designed to be a drop-in replacement for Rust channels. The mapping from the Rust channel APIs to ipc-channel
APIs is as follows:
channel()
→ ipc::channel().unwrap()
Sender<T>
→ ipc::IpcSender<T>
(requires T: Serialize
)Receiver<T>
→ ipc::IpcReceiver<T>
(requires T: Deserialize
)Note that both IpcSender<T>
and IpcReceiver<T>
implement Serialize
and Deserialize
, so you can send IPC channels over IPC channels freely, just as you can with Rust channels.
The easiest way to make your types implement Serialize
and Deserialize
is to use the serde_macros
crate from crates.io as a plugin and then annotate the types you want to send with #[derive(Deserialize, Serialize])
. In many cases, that's all you need to do — the compiler generates all the tedious boilerplate code needed to serialize and deserialize instances of your types.
send()
never blocks.ipc-channel
provides a one-shot server to help establish a channel between two processes. When a one-shot server is created, a server name is generated and returned along with the server.
The client process calls connect()
passing the server name and this returns the sender end of an ipc-channel from the client to the server. Note that there is a restriction in ipc-channel
: connect()
may be called at most once per one-shot server.
The server process calls accept()
on the server to accept connect requests from clients. accept()
blocks until a client has connected to the server and sent a message. It then returns a pair consisting of the receiver end of the ipc-channel from client to server and the first message received from the client.
So, in order to bootstrap an IPC channel between processes, you create an instance of the IpcOneShotServer
type, pass the resultant server name into the client process (perhaps via an environment variable or command line flag), and connect to the server in the client. See spawn_one_shot_server_client()
in integration_test.rs
for an example of how to do this using a command to spawn the client process and cross_process_embedded_senders_fork()
in test.rs
for an example of how to do this using Unix fork()
2 to create the client process.
To run the tests, issue:
Some tests are platform dependent, so for completeness it would be necessary to run the tests on all platforms:
The platforms marked † are covered by CI.
To run the benchmarks, issue:
ipc-channel
is implemented in terms of native IPC primitives: file descriptor passing over Unix sockets on Unix variants, Mach ports on macOS, and named pipes on Windows.
One-shot server names are implemented as a file system path (for Unix variants, with the file system path bound to the socket) or other kinds of generated names on macOS and Windows.
Tony Hoare conceived Communicating Sequential Processes (CSP) as a concurrent programming language. Stephen Brookes and A.W. Roscoe developed a sound mathematical basis for CSP as a process algebra. CSP can now be used to reason about concurrency and to verify concurrency properties using model checkers such as FDR4. Go channels were also inspired by CSP. ↩
fork()
has a number of semantic rough edges and is not recommended for general use. See "A fork() in the road" by Andrew Baumann et al., Proceedings of the Workshop on Hot Topics in Operating Systems, ACM, 2019. (PDF) ↩
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4