Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is accept() thread-safe?

I'm currently writing a simple webserver in C for a course I'm doing. One requirement is for us to implement a thread pool to handle connections using pthreads.

I know how I would go about doing this roughly(calling accept in a main thread and passing the file descriptor to a freee thread), however my friend suggested an alternate method than the one I had in mind: creating all my threads up front, and getting them all to loop forever on a call to accept. The idea being that accept will block all the idle threads and when a connection comes in, only giving the file descriptor to one. Then when a given thread is done with a connection it loops back around and blocks on a call to accept again. Using the call to accept() as a semaphore essentially. This would simplify the implementation quite a bit he figures, as you wouldn't need to keep track of which threads are busy and which are ready for a connection. It would also be lower latency in theory, as the thread can immediately start executing.

My question is, is this safe? I'm planning to implement it and try it out, but I'm not ready yet and I'm quite curious to know the answer. I've searched on google and here on stackoverflow, but couldn't find anyone doing it this way. Is accept thread safe? I assume there will be more overhead with this approach as you are running all your threads all the time, are the two approaches simply a simple memory/latency tradeoff?

Edit: I'm unsure if this should be community wiki, apologies if it should be, I can't find the button :P

like image 758
CalumMcCall Avatar asked Feb 26 '11 00:02

CalumMcCall


People also ask

Which option is thread-safe?

The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.

Is printf () thread-safe?

the standard C printf() and scanf() functions use stdio so they are thread-safe.

Is writing to socket thread-safe?

Writing to a socket by multiple threads is thread-safe as long as the other end can make sense of the intereleaved data. Reading from a socket by multiple threads is thread-safe as long as this end can make sense of the interleaved data.

Is spring boot thread-safe?

How We Achieve Thread Safety In Spring Boot? The default front controller (web server) for spring boot web application is Servlet which it creates a new separate thread for every http request. Servlet then delegates the control flow to the lower layers beginning from controller layer.


3 Answers

Yes. This is a common way to design multithreaded servers and accepted design practice.

You can also fork several times and have the child processes call accept, this will allow you to do multithreading without needing a threads library. Older servers do this.

like image 195
Dietrich Epp Avatar answered Oct 03 '22 16:10

Dietrich Epp


Since this has been bountied, asking for references:

Yes, accept() is thread-safe, as POSIX defines that term.

The relevant reference would be section 2.9.1 of POSIX.1, the current version of which says:

All functions defined by this volume of POSIX.1-2017 shall be thread-safe, except that the following functions need not be thread-safe.

[a list that does not include accept()]

For completeness, POSIX does define accept(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html, so as a POSIX function that does not appear on the list of exceptions, POSIX specifies that it is thread-safe.

like image 24
John Bollinger Avatar answered Oct 03 '22 16:10

John Bollinger


In comments, @Rick (the bounty offerer) says:

In some ways I get the point now. thread-safe would be the property that meets the behaviour. I was thinking thread-safe has to be threads within same process. But now I think there aren't much differences between threads within same process or threads between different processes. In some ways they are the same. So the concept of thread-safety can be applied to both scenarios.

The POSIX definitions regarding thread-safety do indeed refer to threads in the same process (see: §2.9).

If you are asking about what happens after fork(), and if it is safe for the parent and child to concurrently call into accept(), we note first that POSIX defines a system resource known as a connection indication queue. Then we note that the child of fork() gets a copy of the parent's descriptors, and therefore the child and parent will access the same connection indication queue (just as a duplicate file descriptor to a text file would be accessing the same file).

The definition of what accept() does for each process (child and parent) is the same at that point.

like image 25
jxh Avatar answered Oct 03 '22 14:10

jxh