5 个不稳定版本

使用旧 Rust 2015

0.3.0 2017年2月11日
0.2.1 2017年1月11日
0.1.3 2017年1月10日

#chan 中排名 8

MIT 许可证

9KB
110

Build Status codecov MIT licensed docs

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