gpt4 book ai didi

concurrency - 阻止任务,直到 Rust 中的队列不为空

转载 作者:行者123 更新时间:2023-11-29 07:59:09 26 4
gpt4 key购买 nike

我需要在一组任务之间分派(dispatch)作业。 std::sync::deque足以解决这个问题,但如果队列为空,我需要阻塞任务。

以下代码(在 GitHub gist 中可用)是如何使用 std::sync::deque 的工作示例:

extern crate time;

use std::io::timer::sleep;
use std::sync::deque::{BufferPool, Empty, Abort, Data};
use std::time::Duration;

fn main() {

let start = time::precise_time_s();
let pool = BufferPool::new();
let (worker, stealer) = pool.deque();

for task_id in range(1i, 5) {
let sc = stealer.clone();
spawn(proc() {
loop {
let elapse = time::precise_time_s() - start;
match sc.steal() {
Empty => { println!("[{} @ {:#7.4}] No items", task_id, elapse); sleep(Duration::milliseconds(300)) },
Abort => println!("[{} @ {:#7.4}] ABORT. Retrying.", task_id, elapse),
Data(item) => println!("[{} @ {:#7.4}] Found {}", task_id, elapse, item)
}
}
});
}

for item in range(1i, 1000) {
for n in range(1i, 20) {
worker.push(item * n);
}
sleep(Duration::milliseconds(1000));
}

}

我看到有一个std::sync::TaskPool ,但是 current implementation即使线程正忙于旧作业,也将作业发送到任务。

我的问题是:在队列中有任何项目之前阻止任务的最佳方法是什么?

最佳答案

可能的解决方案是使用信号量:

extern crate time;

use std::io::timer::sleep;
use std::sync::deque::{BufferPool, Empty, Abort, Data};
use std::sync::{Semaphore, Arc};
use std::time::Duration;

fn main() {

let start = time::precise_time_s();
let pool = BufferPool::new();
let (worker, stealer) = pool.deque();
let sem = Arc::new(Semaphore::new(0));

for task_id in range(1i, 5) {
let sc = stealer.clone();
let s = sem.clone();
spawn(proc() {
loop {
let elapse = time::precise_time_s() - start;
s.acquire();
match sc.steal() {
Empty => {
println!("[{} @ {:#7.4}] No items", task_id, elapse);
sleep(Duration::milliseconds(300))
},
Abort => {
println!("[{} @ {:#7.4}] ABORT. Retrying.", task_id, elapse);
s.release();
},
Data(item) => println!("[{} @ {:#7.4}] Found {}", task_id, elapse, item)
}
}
});
}

for item in range(1i, 1000) {
for n in range(1i, 20) {
worker.push(item * n);
sem.release();
}
sleep(Duration::milliseconds(1000));
}

}

正如您在这里看到的,您在每个产生的值上释放一个信号量资源,并在从队列中获取值之前获取它。在这种情况下,返回值永远不会为空,但仍然有可能中止,您必须释放资源,因为没有读取任何内容,但值仍在队列中。

另一种可能的解决方案也是使用在没有所需值时阻塞的 channel 。对于性能,您必须对这两种解决方案进行基准测试。

关于concurrency - 阻止任务,直到 Rust 中的队列不为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25941576/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com