Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust concurrency #8

Open
rkrzr opened this issue May 16, 2023 · 4 comments
Open

Rust concurrency #8

rkrzr opened this issue May 16, 2023 · 4 comments

Comments

@rkrzr
Copy link

rkrzr commented May 16, 2023

Hey @robinaidev, what are the top 3 ways to write a concurrent program in Rust? Please elaborate on the pros and cons of each approach and compare them to each other.

@robinaidev
Copy link

Hello @rkrzr! Rust provides several ways to write concurrent programs. Three commonly used ways are:

  1. Using threads and message passing with channels.
  2. Using shared memory concurrency with mutexes.
  3. Using async/await with Tokio or async-std libraries.

Each approach has its own advantages and disadvantages. Using threads with message passing provides good control over resources and is easier to reason about. However, it can be harder to debug and performance may be slower than alternatives.

Using shared memory concurrency with mutexes is faster than using threads with message passing. It works well for programs that need to share data between threads, but can also lead to race conditions and deadlocks that are harder to debug.

Using async/await with Tokio or async-std libraries can be the most efficient way to write concurrent programs, especially those that need to handle a lot of I/O. However, it can be harder to understand and write due to its complexity.

Overall, the choice of approach depends on the specific requirements of the program.

@marcelosousa
Copy link
Member

The key thing here is that we can now have a conversation @rkrzr . @robinaidev can decide when it should reply.

@marcelosousa
Copy link
Member

@robinaidev can you share some code examples on each of the three commonly used ways?

@robinaidev
Copy link

Sure, here are some code examples for each approach:

  1. Using threads and message passing with channels:
use std::thread;
use std::sync::mpsc;

fn main() {
    let (sender, receiver) = mpsc::channel();

    for i in 0..10 {
        let child_sender = sender.clone();
        thread::spawn(move || {
            child_sender.send(i).unwrap();
        });
    }

    for _ in 0..10 {
        println!("{}", receiver.recv().unwrap());
    }
}
  1. Using shared memory concurrency with mutexes:
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", *counter.lock().unwrap());
}
  1. Using async/await with Tokio or async-std libraries:
use std::error::Error;
use tokio::io::{self, AsyncReadExt};
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (mut socket, _) = listener.accept().await?;

        tokio::spawn(async move {
            let mut buf = [0; 1024];

            loop {
                let n = match socket.read(&mut buf).await {
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                if let Err(e) = socket.write_all(&buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}

I hope these code examples help you understand the three approaches better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants