Rust lang series episode #30 — channels (#rust-series)

in #rust-series8 years ago (edited)

Hello everyone, 30th Rust lang series episode is here. In previous episode, we were working with multiple threads. Today we will extend it with knowledge of channels.

Channels

Channel in Rust is facility to send and receive data across threads. Chanel sends generic signal and we can also send any data over the channel.

Creating channel

let (tx,rx) = mpsc::channel();

tx is channel Transmitter/Sender
rx is channel Receiver

With channels we can achieve two types of communication

  • asynchronous buffered channel from Sender to Receiver
  • synchronous buffered channel from SyncSender to Receiver

Sending data

tx.send(10).unwrap();

Sending number via channels

fn main() {
    use std::thread;
    use std::sync::mpsc::channel;

    let (tx, rx) = channel();
    thread::spawn(move || {
        tx.send(10).unwrap();
    });


    println!("Data from channel received: {}",rx.recv().unwrap());
}

Breaking down

channel() function creates transaction channel providing tuple with transmitter and receiver.

send() method sends value over channel to a receiver

recv() waits for channel to receive sent data

Again consider finer error handling for send() and recv().

Multiple threads example

Now we can boost this example to create multiple threads and receive their data via channels. This will compute third power on each thread for numbers from 0 to 9.

use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    for i in 0..10 {
        let tx = tx.clone();

        thread::spawn(move || {
            let answer = i * i * i;

            tx.send(answer).unwrap();
        });
    }

    for _ in 0..10 {
        println!("{}", rx.recv().unwrap());
    }
}

Output

0
8
27
...

Note that result order can vary.

Breaking down

There is actually nothing unknown here except we use clone() to create copy of transmitter for each thread. And we call recv() in cycle to capture channel data one by one.

Heating up your CPU

Well, so far we've used threads for operations that can be easily done on single thread. But we can see true performance upgrade when we try to compute big numbers for example. Check this modified example that will compute factorial for number in range from 10,000 to 10,020. This will finally work your CPU hard. We will need crate for big numbers so add this to your Cargo.toml

num = "*"

And code can look like this to perform big number factorization.

extern crate num;

use num::{BigUint, One, FromPrimitive};
use std::mem::replace;
use std::thread;
use std::sync::mpsc;

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

fn main() {
    let (tx, rx) = mpsc::channel();

    for i in 10000..10020 {
        let tx = tx.clone();

        thread::spawn(move || {
            let answer = factorial(i);
            let res = (i, answer);
            tx.send(res).unwrap();
        });
    }

    for n in 0..20 {
        let (n,res) = rx.recv().unwrap();
        println!("{}!={}", n, res);
    }

    println!("Computation finished!");
}

Output

10003!=28479677...
10000!=28462...
Computation finished!

When you run this you can see all cores (unless you have more than 20 cores :)) of your CPU fully utilized! Code utilizes BigUint from num crate to compute numbers much bigger than the range of 64-bit integers. Note that the work with num crate is little bit less comfortable than with built-in primitive numeric types but on the other hand we can work with really big numbers which is exactly what we need here.

Postfix

That's all for now, thank you for your appreciations, feel free to comment and point out possible mistakes (first 24 hours works the best but any time is fine). May Jesus bless your programming skills, use them wisely and see you next time.

Meanwhile you can also check the official documentation for additional related information:

#rust-series
#rust-lang
#rust

Coin Marketplace

STEEM 0.23
TRX 0.18
JST 0.031
BTC 86585.64
ETH 3132.20
USDT 1.00
SBD 3.01