Synchronous concurrency: Difference between revisions
Content added Content deleted
(Added Rust.) |
|||
Line 1,895: | Line 1,895: | ||
* The queue of <tt>lines</tt> can become long; the worst case allows the reader to read the entire file before the printer pops the first line! If you wanted to prevent a long queue, a <tt>SizedQueue.new(5)</tt> would hold only 5 elements. |
* The queue of <tt>lines</tt> can become long; the worst case allows the reader to read the entire file before the printer pops the first line! If you wanted to prevent a long queue, a <tt>SizedQueue.new(5)</tt> would hold only 5 elements. |
||
* If <tt>IO.reader</tt> raises an IO error, then the reader dies. The writer would deadlock on an empty queue after the reader dies. To prevent this deadlock, the reader ensures to queue a final <tt>nil</tt> before it dies. The writer uses this <tt>nil</tt> to break its loop and call <tt>reader.join</tt>. If the reader dies with an IO error, then <tt>reader.join</tt> raises the same error. |
* If <tt>IO.reader</tt> raises an IO error, then the reader dies. The writer would deadlock on an empty queue after the reader dies. To prevent this deadlock, the reader ensures to queue a final <tt>nil</tt> before it dies. The writer uses this <tt>nil</tt> to break its loop and call <tt>reader.join</tt>. If the reader dies with an IO error, then <tt>reader.join</tt> raises the same error. |
||
=={{header|Rust}}== |
|||
{{works with|rustc 1.4.0-nightly|f84d53ca0 2015-09-06}} |
|||
<lang rust>use std::fs::File; |
|||
use std::io::BufReader; |
|||
use std::io::BufRead; |
|||
use std::thread::spawn; |
|||
use std::sync::mpsc::{SyncSender, Receiver, sync_channel}; |
|||
fn main() { |
|||
let (tx, rx): (SyncSender<String>, Receiver<String>) = sync_channel::<String>(0); |
|||
// Reader thread. |
|||
spawn(move || { |
|||
let file = File::open("input.txt").unwrap(); |
|||
let reader = BufReader::new(file); |
|||
for line in reader.lines() { |
|||
match line { |
|||
Ok(msg) => tx.send(msg).unwrap(), |
|||
Err(e) => println!("{}", e) |
|||
} |
|||
} |
|||
drop(tx); |
|||
}); |
|||
// Writer thread. |
|||
spawn(move || { |
|||
let mut loop_count: u16 = 0; |
|||
loop { |
|||
let recvd = rx.recv(); |
|||
match recvd { |
|||
Ok(msg) => { |
|||
println!("{}", msg); |
|||
loop_count += 1; |
|||
}, |
|||
Err(_) => break // rx.recv() will only err when tx is closed. |
|||
} |
|||
} |
|||
println!("Line count: {}", loop_count); |
|||
}).join().unwrap(); |
|||
}</lang> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |