I am using Linux 3.2.0, x86_64. Can I call accept() for one socket from several threads simultaneously?
Asked
Active
Viewed 7,349 times
9
-
possible duplicate of [Is accept() thread-safe?](http://stackoverflow.com/questions/5124320/is-accept-thread-safe) – alk Feb 15 '14 at 15:30
1 Answers
13
Yes, you can call accept()
on the same listening socket from multiple threads and multiple process though there might not be as much point to it as you think. The kernel will only allow one to succeed. When this is done with processes it is known as pre-forking and it saves the expense of a fork()
for every new connection. But when you are dealing with threads you can more easily have an existing thread pool that waits on a queue of new connections. One thread does the accept
and writes the queue and the worker threads read the queue and do their thing. It's cleaner, it's a well understood pattern, and you lose almost nothing.

Duck
- 26,924
- 5
- 64
- 92
-
From opengroup.org, listen() function: "The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue." There is a queue already, we shouldn't need another. – alkedr Jul 15 '12 at 00:52
-
If you say so. Just keep in mind there are reasons why best practices emerge. – Duck Jul 15 '12 at 01:09
-
1
-
1backlog queue is advisory & you don't have much control w/o being root; it normally isn't very large and tcp starts rejecting connections when it is full. You can control your own queue more easily and accept many more connections and handle them as needed with your various threads and/or multiplexing. If you want to temporarily stop accepting connections you have multiple threads to attempt to reign in not just one. If you want to shut down your threads you may have to start blowing them out while they block on accept rather than cleanly. It makes load balancing harder. Off top of head. – Duck Jul 15 '12 at 01:38
-
Earlier versions of `accept` would serialize access to the system call, but would wake up all threads/processes when it became available, resulting in the [thundering herd problem](http://en.wikipedia.org/wiki/Thundering_herd_problem), which a properly implemented secondary queue solves. I am not sure if `accept` still has this issue anymore, though. – jxh Jul 15 '12 at 01:40
-
I will use a second queue. Thank you for great answers, @Duck and @user315052! :) – alkedr Jul 15 '12 at 01:47
-
@Duck default size for the backlog queue is at least 500 these days. – user207421 Jul 15 '12 at 01:53
-
@EJP the /proc/sys/net/core/somaxconn default is 128 on my machine and that is also what `man (2) listen` lists. More than enough for most things but not exactly a cornucopia in a 10k world. – Duck Jul 15 '12 at 02:18
-
Whay I usually do is raise the priority of the 'accept' listening thread or reduce the priority of the server<>client threads. The listening queue is then serviced promptly and does not overflow. – Martin James Jul 15 '12 at 06:40
-
@user315052: no thundering herd in Linux for accept() since 2.2 times, more than a decade ago. – ninjalj Jul 15 '12 at 20:32
-
-
@user315052: Unfortunately no, it just means I was paying more attention to the networking stack. – ninjalj Jul 16 '12 at 18:45