5 个不稳定版本
使用旧 Rust 2015
0.3.0 | 2017年2月11日 |
---|---|
0.2.1 | 2017年1月11日 |
0.1.3 | 2017年1月10日 |
在 #chan 中排名 8
9KB
110 行
POSIX 进程间的 Rust 同步通道
陶瓷是一种简单而有效的方法,可以将糟糕的代码隔离到进程中。代码有自己的堆,并且可以在不影响主进程的情况下被终止。
它与 servo/ipc-channel 实现了相同的使用案例,但设计更加一致和简单。缺点是它可能不支持 Windows。
这是原始 C++ 库的 Rust 版本 https://github.com/aep/ceramic。
所有通过通道传递的类型都需要序列化和反序列化特性。
use ceramic;
fn main() {
let chan = ceramic::channel().unwrap();
let _p = ceramic::fork(|| {
chan.send(&String::from("hello")).unwrap();
});
chan.set_timeout(Some(::std::time::Duration::new(1,0))).unwrap();
let s : String = chan.recv().unwrap_or(Nothing).unwrap_or(String::from("nothing"));
println!("{}", s);
}
或者用作迭代器
fn main() {
let chan = ceramic::channel().unwrap();
let _p = ceramic::fork(|| {
chan.send(&String::from("herp")).unwrap();
chan.send(&String::from("derp")).unwrap();
chan.close().unwrap();
});
for s in chan {
println!(">>{}<<", s.unwrap());
}
}
通道同步行为
发送和接收操作 必须是 对称的。也就是说,一个 read() 将会阻塞,直到另一个线程调用 write(),但 write() 也会阻塞,直到有读取。这基本上是 go 语言 chan(0) 的行为,而不是 通常的 Unix IPC 的行为。
这使得使用陶瓷的代码更容易理解,因为它引入了同步点。
primes = chan();
thread() {
do {
int nr = heavyMath();
} while (chan << nr)
}
primes >> nr;
primes >> nr;
primes >> nr;
primes.close();
然而,这也引入了新的竞争条件,这在带有缓冲的通道中是不存在的,例如,以下是不合法的
thread() {
write();
}
thread() {
read();
}
write();
read();
这可能看起来像
- 创建一些线程 A 和 B 并等待
- 然后向线程 B 写入
- 并从线程 A 读取
但操作系统调度器可能会随机决定这个顺序
- 创建一些线程 A、B 并等待
- A 写入 B
- 主线程在写入时死锁
在 go 语言中有一个论点,你应该只在代码不使用缓冲时使用缓冲通道,以避免这种情况,即由于缓冲而不死锁。但对于读者来说,代码流仍然完全不清楚。
待办事项
- 清理未使用套接字的 API
- 关闭写入的语义不明确
- 使用 pthread 进行测试
- 死锁检测
- 在 osx 上进行测试
依赖项
~8.5MB
~162K SLoC