Created
March 5, 2018 19:28
-
-
Save autodidaddict/b7e5a2d051b8430a5cd88fc302b84eb7 to your computer and use it in GitHub Desktop.
Mutating Data with Multiple Threads in Rust - Channels vs Mutexes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::thread::spawn; | |
use std::sync::Arc; | |
use std::sync::Mutex; | |
use std::sync::mpsc; | |
#[derive(Debug)] | |
struct Transaction { | |
amount: isize, | |
timestamp: u64, | |
txid: String, | |
} | |
#[derive(Debug)] | |
struct Account { | |
account_number: String, | |
transactions: Mutex<Vec<Transaction>>, | |
acct_type: String, | |
} | |
#[derive(Debug)] | |
struct Account2 { | |
account_number: String, | |
transactions: Vec<Transaction>, | |
acct_type: String, | |
} | |
impl Account { | |
pub fn new(account_number: &str) -> Account { | |
Account { | |
account_number: account_number.to_owned(), | |
acct_type: "Savings".to_owned(), | |
transactions: Mutex::new(Vec::new()), | |
} | |
} | |
} | |
fn main() { | |
let my_savings = Arc::new(Account::new("0001")); | |
let feed_account = my_savings.clone(); // clones the ref, not the item | |
let mobile_account = my_savings.clone(); | |
let file_feed = spawn(move || { | |
let mut tx_guard = feed_account.transactions.lock().unwrap(); | |
tx_guard.push(Transaction { | |
amount: 500, | |
timestamp: 12, | |
txid: "tx-001".to_owned(), | |
}); | |
tx_guard.push( Transaction { | |
amount: 750, | |
timestamp: 4, | |
txid: "tx-002".to_owned(), | |
}) | |
}); | |
let mobile_feed = spawn(move || { | |
mobile_account.transactions.lock().unwrap().push(Transaction { | |
amount: 50, | |
timestamp: 7, | |
txid: "tx-003".to_owned(), | |
}); | |
}); | |
file_feed.join().unwrap(); | |
mobile_feed.join().unwrap(); | |
println!("mutating from bg threads:\n\t{:?}", my_savings.transactions); | |
let (tx, rx) = mpsc::channel(); | |
let tx2 = mpsc::Sender::clone(&tx); | |
let file_feed2 = spawn(move || { | |
tx.send(Transaction { | |
amount: 500, | |
timestamp: 12, | |
txid: "ch-tx-001".to_owned(), | |
}).unwrap(); | |
tx.send(Transaction { | |
amount: 750, | |
timestamp: 4, | |
txid: "ch-tx-002".to_owned(), | |
}).unwrap(); | |
}); | |
let mobile_feed2 = spawn(move || { | |
tx2.send(Transaction { | |
amount: 50, | |
timestamp: 7, | |
txid: "ch-tx-003".to_owned(), | |
}).unwrap(); | |
}); | |
file_feed2.join().unwrap(); | |
mobile_feed2.join().unwrap(); | |
let mut tl_savings = Account2 { | |
acct_type: "Savings".to_owned(), | |
account_number: "0001".to_owned(), | |
transactions: Vec::new(), | |
}; | |
for transaction in rx { | |
tl_savings.transactions.push(transaction); | |
} | |
println!("mutating in single thread, collected from channels:\n\t{:?}", tl_savings.transactions); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment