Socket per Thread in Tokio

Hello, I see seem to use 1 thread per socket.
I Think Many Thread is not good.
I don't know how to use like a IOCP (windows model) in rust.
Would you mind looking at my code?


#[tokio::main]
async fn main() {

    // Bind the listener to the address
    let listener = TcpListener::bind("127.0.0.1:3333").await.unwrap();
    println!(" server on port : 3333");

    let mut icount = 0;

    let (tx, rx) = broadcast::channel(16);    
    loop{
        let (mut _socket, _addr) = listener.accept().await.unwrap();    

        let mut user = user::userinfo{            
            uuid : uuid::Uuid::new_v4(),
            addr : _addr,
            stream : Cell::new(_socket)
        };

        icount+=1;
        println!("uuid : {}, count {}", user.uuid, icount);
        
        register_user(user, tx.clone()).await;
    }
}

async fn register_user(mut user : user::userinfo, tx : tokio::sync::broadcast::Sender<(String, uuid::Uuid)>) {       
    
    let mut clone_rx = tx.subscribe();

    // I don;t want to create Thread...
    let handle = tokio::spawn(async move{
       
        println!("Create Thread User");

        let (read_s, mut write_s) = user.stream.get_mut().split();
        let mut reader = BufReader::new(read_s);
        let mut line = String::new();

        loop {            
            tokio::select! {                              

                result = reader.read_line(&mut line)=>{                     
                    match result{
                        Ok(len)=>{
                            if len == 0 {
                                println!(" === Disconnect Socket uuid: {}" , user.uuid);
                                break;
                            }
                            
                            tx.send((line.clone(), user.uuid)).unwrap();                            
                            line.clear();
                        },
                        Err(e) =>{
                            let value =  e.to_string();
                            //println!("=== Error :{}, {}" ,user.uuid, String::from_utf8_lossy(&valuep));
                            println!("===={:?} ", value);
                            return;
                        }
                    };
                }

                result = clone_rx.recv() =>{
                    let (msg, uuid) = result.unwrap();                           
                    //println!("-> {}", msg);
                    if user.uuid != uuid{
                          write_s.write_all(msg.as_bytes()).await.unwrap();                
                    }                                             
                }
            }
        }
        
    }); // thread

    //handle.await.unwrap();
    println!("=== user connected ===");
}

When I recv or write that create Thread.
How to fix it?

The tokio::spawn function does not create a new thread.

Rellay? I didn't know.

The entire point of async/await is to avoid spawning a thread when you call tokio::spawn.

Don't I have to use 'Spawn' in the end to receive or write?

I'm not sure I understand.

tokio::spawn does not create a thread; it creates a Tokio task, which is a co-operatively scheduled entity that Tokio knows how to schedule on the Tokio runtime (in turn, the Tokio runtime can have as many worker threads as you want - from 1 upwards).

By using tokio::spawn, you allow the Tokio runtime to switch to another task at points in the task where it has a .await, and only those points. Your alternative, if you don't want multiple tasks, is to use things like select!, join! and functions with select or join in their name to have concurrent I/O in a single task.

The point of spawning in Tokio is twofold:

  1. If your runtime has multiple threads, then two tasks can execute in parallel on different threads, reducing latency.
  2. It is almost always easier to understand a complex program in terms of different tasks doing their work, than in terms of a single large task doing lots of work concurrently (e.g. using select to wait for one of many options, or join to wait for all options to finish).
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.