[英]Block a task until a queue is not empty in Rust
我需要在一组任务之间分配工作。 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 ,但是当前的实现将作业发送到任务,即使线程忙于旧作业。
我的问题是:在队列中有任何项目之前阻止任务的最佳方法是什么?
可能的解决方案是使用信号量:
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));
}
}
正如您在此处所看到的,您在生成的每个值上释放信号量资源,并在从队列中获取值之前获取它。 在这种情况下,返回的值永远不会为空,但仍然可以执行Abort,并且必须释放资源,因为没有读取任何内容但值仍在队列中。
另一种可能的解决方案是使用在没有任何值时阻止的通道。 为了获得性能,您必须对两种解决方案进
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.