I'm currently buiding an application where I have a Unix socket and for each client, a new thread is spawned and calls a handler which will listen for the client's message. This seems to be the go-to method to handle messages concurrently.
The problem I have is that this thread never exits! This means I get a lot of dangling threads once the client disconnected.
How can I do to check if the listener isn't listening anymore and make the listener's thread exit?
Thanks in advance for your help!
You can set a read timeout on the stream
this thread never exits!
Which thread do you mean? The one thread that's listening for new connections and spawning connection threads, or the connection threads themselves?
The listening thread doesn't need to exit unless the app's being shut down. The connection threads will normally just exit once their connection socket is closed.
There are really many ways to handle this. You can try detecting if the client disconnects from the thread and exiting. Basically if your read returns 0 bytes, then the client probably disconnected. Timeout is another way, like @semicoleon pointed out.
However, this is also a good chance to think if your design is correct or good. What are your threads doing? Is it a long-term communication or not? I would recommend to maybe design a communication protocol between client and server (just basically make up some control commands, nothing complicated), if your communication is complex. Are just sending some data, like a file over?
You can try using thread pool instead, which also will allow you not to constantly create threads. You can also try using async methods and see if they will be better.
Btw, it might be better if you show your code that spawns the thread and listens to the socket, this way you can get more concrete help.
I'm talking about the connection threads. The main listening thread will of course stay alive for the application's lifetime, but I want to make the connection threads exit when the client itself exits.
Ok so if a read returns 0 bytes then it means the client disconnected?
Currently I'm using a
loop in which I use a
BufReader::lines wrapper (as each client request is on a single line and ends with a newline symbol).
The clients are normally short-lived but there's no guarantee of it.
Yes, at least according to the doc on the trait Read Read in std::io - Rust
You should also catch an error with the match statement, as that is also a possibility, but essentially you would be getting Ok(0) all the time after the client disconnects. if you want to be certain, you can try to implement a "close out" protocol, something like, if you get a 0 byte read, sleep for 2 seconds and try again, if you get a 0 byte read again - exit.
I also recommend looking into a thread pool and async. When you spawn threads, they each get own stacks, so they take a up a good amount of ram, so if you are going to have many clients at once, it is possible to run out of ram just from thread overhead. Async functions are better in this regards and with threadpool you don't need waste time on reallocating memory all the time
Ok(0) means the socket is disconnected. Although on Windows, I sometimes get an error on disconnect, rather than
Ok(0). I don't know why.
I have never used
BufReader::lines() to read lines from a socket, but I think it should work OK.
On socket disconnect, your thread function should simply return, which will terminate the thread. There won't be any dangling threads.
This is normal behavior and it will vary depending on the OS and how it handles sockets and streams.
Ok, thanks everyone for your answers
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.