背景工作者螺纹和同步在Rust

时间:2017-12-21 03:07:06

标签: multithreading rust

我正在尝试编写一个简单的库,它有一个后台工作线程,可以在调用库函数时处理命令。

我通常在C中执行此操作的方式是具有工作程序将阻止的全局信号量句柄。函数在发送命令后会给出信号量,此时工作人员会解锁等等......还有其他方法,但这只是一个例子。

我有一些关于如何使用Rust实现类似功能的问题。

  1. 如果线程在创建它的函数返回后阻止线程关闭?例如,当我呼叫init()时会创建该线程,但是当init()返回时会退出,如何防止这种情况?

  2. 如何在工作线程和函数调用之间建立全局同步方法?我正在考虑使用频道,但如何从线程中访问rx以及从不同的函数访问多个tx?例如send_cmd_a()send_cmd_b()到同一个帖子

  3. 我想要完成的伪代码:

    static (tx, rx) = mpsc::channel(); //how to do something like this?
    
    fn init() {
        thread::spawn(|| {
            loop {
                let cmd = rx.recv().unwrap(); //blocks till there is data
                                              //process data....
                if cmd == "exit" {
                    return;
                }
            }
        });
    }
    
    fn send_cmd_a() {
        //Do a bunch of other stuff...
        tx.send("cmd_a").unwrap();
    }
    
    fn exit() {
        tx.send("exit").unwrap();
    }
    

    我是否必须创建一个封装所有这些内容的大对象,从而拥有同步机制? (仍然没有回答问题#1)

    在Rust中做这样的事情的首选方法是什么?

1 个答案:

答案 0 :(得分:1)

我想我找到了一种在Rust中实现我想要的方法,而不需要使用全局变量。

struct Device {
    sender: Sender<u8>, //other stuff
}

trait New {
    fn new() -> Self;
}

trait SendCommand {
    fn send_command(&self, u8);
}

impl New for Device {
    fn new() -> Device {
        let (tx, rx) = channel();
        let device = Device { sender: tx };
        thread::spawn(move || {
            loop {
                let cmd = rx.recv().unwrap();
                println!("Command: {}", cmd); //process commands here
            }
        });
        return device;
    }
}

impl SendCommand for Device {
    fn send_command(&self, cmd: u8) {
        self.sender.send(cmd).unwrap();
    }
}

fn main() {
    let dev = Device::new(); //create the device
    for i in 0..10 {
        dev.send_command(i); //send commands
        sleep(Duration::from_millis(50));
    }
    loop {}
}