Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are my Rust threads not running in parallel?

I wish to spin up X threads which will fire X requests to the specified server within the code. Currently, my application is waiting for each thread and X requests to finish before spinning up the next one.

How can I go about doing this async?

extern crate hyper;
extern crate time;

use hyper::header::Connection;
use hyper::Client;
use std::sync::{Arc, Mutex};
use std::thread;
use time::*;

struct Request {
    elapsed_time: f64,
}

impl Request {
    fn new(elapsed_time: f64) -> Request {
        Request {
            elapsed_time: elapsed_time,
        }
    }
}

fn main() {
    let requests = Arc::new(Mutex::new(Vec::new()));

    for _x in 0..100 {
        println!("Spinning up thread...");

        let mut client = Client::new();
        let thread_items = requests.clone();

        let handle = thread::spawn(move || {
            for _x in 0..100 {
                println!("Firing the request");
                let start = time::precise_time_s();

                let _res = client
                    .get("http://jacob.uk.com")
                    .header(Connection::close())
                    .send()
                    .unwrap();

                let end = time::precise_time_s();

                thread_items
                    .lock()
                    .unwrap()
                    .push((Request::new(end - start)));
            }
        });

        handle.join().unwrap();
    }
}

Program output:

Spinning up thread...
Firing request
Firing request
Firing request
Firing request
Spinning up thread...
Firing request
Firing request
Firing request
Firing request
Spinning up thread...
Firing request
Firing request
Firing request
Firing request
like image 486
Jacob Clark Avatar asked Jun 01 '15 08:06

Jacob Clark


People also ask

How many threads can Rust run?

The threads provided by the Rust standard library are "OS threads", that is, they use the facilities of your operating system. Therefore, a Rust program has no limit imposed by Rust itself, but rather, this limit would result from whatever your OS lets you do.

Does Rust have multi threading?

The Rust standard library uses a 1:1 model of thread implementation, whereby a program uses one operating system thread per one language thread. There are crates that implement other models of threading that make different tradeoffs to the 1:1 model.

What does spawning a thread mean?

Spawning a new physical thread will mean a transition into Kernel mode and setting up a bunch of mernel structures, so the overhead will be higher.

Does Rust have green threads?

Rust, in fact, has a history with green threads. A green threads runtime used to be the default paradigm for Rust code.


1 Answers

Your culprit is this line:

handle.join().unwrap();

You execute a thread in the loop, and then right after starting the thread you join it into the main thread.

What you could do, is to create a Vec and put all the handles in the vec. Then, in another loop, you join all the handles.

Another possibility is to simply not join the threads, and let them exit naturally, but then you won't know when all of them are done. Which, as @delnan notes, might allow the main thread to exit before the spawned threads exit. This causes all the spawned threads to be killed instead of letting them run to termination.

like image 199
oli_obk Avatar answered Nov 16 '22 01:11

oli_obk