title: SO_REUSEPORT with epoll and multiple process
body: <p>In a nutshell, <code>SO_REUSEPORT</code> socket option allow to create multiple sockets on ip:port pair. For example, <code>program1</code> and <code>program2</code> both can call functions chain <code>socket()-&gt;bind()-&gt;listen()-&gt;accept()</code> for the same port and IP, and kernel scheduler will evenly distribute incoming connections between this two programs.</p>
  
  <p>I assumed that with this option, you can get rid of the use of <code>fork()</code> for spawning additional workers and can simply run new program instance.</p>
  
  <p>I wrote a simple epoll socket server, based on this logic, and test it with weighttp:</p>
  
  <p><code>weighttp -n 1000000 -c 1000 -t 4 http://127.0.0.1:8080/</code></p>
  
  <p>For two running instances the results is ~44000 RPS, for one running instance - near ~51000 RPS. I am very surprised with 7000 RPS differece. </p>
  
  <p>After this test I add <code>fork()</code> before <code>listen()</code> and run one instance of server, so now it has the same logic that previous implementation - two process with epoll loop listening socket, but <code>socket()-&gt;bind()</code> called only once, before <code>fork()</code>, and second process receive it FD copy for <code>listen()</code> call.</p>
  
  <p>I run tests again and it shows ~50000 RPS!</p>
  
  <p>So, my question is very simple: what magic do <code>fork()</code> in this case and why it works faster than two independent process with it own <code>socket()</code>? Kernel do the same job for scheduling, I dont see any important difference.</p>