▲ | kev009 5 days ago | ||||||||||||||||||||||
It wasn't just CGI, every HTTP session was commonly a forked copy of the entire server in the CERN and Apache lineage! Apache gradually had better answers, but their API with common addons made it a bit difficult to transition so webservers like nginx took off which are built closer to the architecture in the article with event driven I/O from the beginning. | |||||||||||||||||||||||
▲ | avar 5 days ago | parent | next [-] | ||||||||||||||||||||||
And there's nothing wrong with that for application workers. On *nix systems fork() is very fast, you can fork "the entire server" and the kernel will only COW your memory. As nginx etc. showed you can get better raw file serving performance with other models, but it's still a legitimate technique for application logic where business logic will drown out any process overhead. | |||||||||||||||||||||||
| |||||||||||||||||||||||
▲ | jabl 5 days ago | parent | prev | next [-] | ||||||||||||||||||||||
To nitpick at least as of Apache HTTPD 1.3 ages ago it wasn't forking for every request, but had a pool of already forked worker processes with each handling one connection at a time but could handle an unlimited number of connections sequentially, and it could spawn or kill worker processes depending on load. The same model is possible in Apache httpd 2.x with the "prefork" mpm. | |||||||||||||||||||||||
| |||||||||||||||||||||||
▲ | tliltocatl 5 days ago | parent | prev [-] | ||||||||||||||||||||||
That's because Unix API used to assume fork() is extremely cheap. Threads were ugly performance hack second-class citizens - still are in some ways. This was indeed true on PDP-11 (just copy a <64KB disk file!), but as address spaces grew, it became prohibitively expensive to copy page tables, so programmers turned to multithreading. At then multicore CPUs became the norm, and multithreading on multicore CPUs meant any kind of copy-on-write required TLB shootdown, making fork() even more expensive. VMS (and its clone known as Windows NT) did it right from the start - processes are just resource containers, units execution are threads and all IO is async. But being technically superior doesn't outweighs the disadvantage of being proprietary. | |||||||||||||||||||||||
|