แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒจแƒ”แƒกแƒแƒ•แƒแƒšแƒ˜

I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ (แƒ”แƒ แƒ— แƒซแƒแƒคแƒ˜แƒแƒœแƒ˜ แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒชแƒ˜แƒ™แƒšแƒ˜) แƒแƒ แƒ˜แƒก แƒ›แƒแƒฆแƒแƒšแƒ˜ แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒฃแƒšแƒ˜ แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒ˜แƒก แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒœแƒ˜แƒ›แƒฃแƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ‘แƒ”แƒ•แƒ  แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒš แƒ’แƒแƒ“แƒแƒฌแƒงแƒ•แƒ”แƒขแƒแƒจแƒ˜:

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ“แƒแƒ•แƒฎแƒ”แƒ“แƒแƒ•แƒ— I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒฌแƒ•แƒ“แƒแƒ›แƒแƒก แƒ“แƒ แƒฌแƒ•แƒ“แƒแƒ›แƒแƒก แƒ“แƒ แƒ แƒแƒ’แƒแƒ  แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒ˜แƒ’แƒ˜, แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ— แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒแƒก แƒ™แƒแƒ“แƒ˜แƒก 200 แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ–แƒ” แƒœแƒแƒ™แƒšแƒ”แƒ‘ แƒฎแƒแƒ–แƒจแƒ˜ แƒ“แƒ แƒ“แƒแƒ•แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ— แƒ›แƒแƒ แƒขแƒ˜แƒ• HTTP แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒก 40 แƒ›แƒ˜แƒšแƒ˜แƒแƒœ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒ–แƒ”/แƒฌแƒ—.

แƒฌแƒ˜แƒœแƒแƒกแƒ˜แƒขแƒงแƒ•แƒแƒแƒ‘แƒ

  • แƒกแƒขแƒแƒขแƒ˜แƒ แƒ“แƒแƒ˜แƒฌแƒ”แƒ แƒ แƒ˜แƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒ’แƒแƒ•แƒ˜แƒ’แƒแƒ— I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ แƒ“แƒ, แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒ’แƒแƒ•แƒ˜แƒ’แƒแƒ— แƒ แƒ˜แƒกแƒ™แƒ”แƒ‘แƒ˜ แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก.
  • แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ’แƒแƒกแƒแƒ’แƒ”แƒ‘แƒแƒ“ แƒกแƒแƒญแƒ˜แƒ แƒแƒ แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒ”แƒ‘แƒ˜แƒก แƒชแƒแƒ“แƒœแƒ. C แƒ”แƒœแƒ แƒ“แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ แƒฅแƒกแƒ”แƒšแƒ˜แƒก แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒแƒจแƒ˜.
  • แƒงแƒ•แƒ”แƒšแƒ แƒ™แƒแƒ“แƒ˜ แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ C แƒ”แƒœแƒแƒ–แƒ” แƒ›แƒ™แƒแƒชแƒ แƒแƒ“ (แƒกแƒ˜แƒคแƒ แƒ—แƒฎแƒ˜แƒšแƒ”: แƒ’แƒ แƒซแƒ”แƒšแƒ˜ PDF) C11 แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒ˜แƒ— Linux-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ“แƒ แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ GitHub.

แƒ แƒแƒขแƒแƒ› แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ”แƒœ แƒแƒ›แƒแƒก?

แƒ˜แƒœแƒขแƒ”แƒ แƒœแƒ”แƒขแƒ˜แƒก แƒ›แƒ–แƒแƒ แƒ“แƒ˜ แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒแƒ‘แƒ˜แƒ—, แƒ•แƒ”แƒ‘ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒก แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ“แƒแƒ— แƒ”แƒ แƒ—แƒ“แƒ แƒแƒฃแƒšแƒแƒ“ แƒ“แƒ˜แƒ“แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒ— แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ แƒ“แƒ, แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒกแƒชแƒแƒ“แƒ”แƒก แƒแƒ แƒ˜ แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ: I/O-แƒก แƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ“แƒ˜แƒ“ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒแƒ–แƒ” แƒ“แƒ I/O-แƒก แƒ“แƒแƒฃแƒ‘แƒšแƒแƒ™แƒแƒ•แƒ˜ แƒ™แƒแƒ›แƒ‘แƒ˜แƒœแƒแƒชแƒ˜แƒ˜แƒ—. แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒแƒกแƒ”แƒ•แƒ” แƒฃแƒฌแƒแƒ“แƒ”แƒ‘แƒ”แƒœ "แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ›แƒ แƒฉแƒ”แƒ•แƒ”แƒšแƒก" (แƒ”แƒžแƒแƒšแƒ˜/แƒ แƒ˜แƒ’แƒจแƒ˜/IOCP/ แƒ“แƒ แƒ.แƒจ.).

แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ แƒ›แƒแƒ˜แƒชแƒแƒ•แƒ“แƒ แƒแƒฎแƒแƒšแƒ˜ OS แƒซแƒแƒคแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒแƒก แƒงแƒแƒ•แƒ”แƒšแƒ˜ แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ›แƒ˜แƒกแƒ˜ แƒ›แƒ˜แƒœแƒฃแƒกแƒ˜ แƒแƒ แƒ˜แƒก แƒชแƒฃแƒ“แƒ˜ แƒ›แƒแƒกแƒจแƒขแƒแƒ‘แƒ˜แƒ แƒ”แƒ‘แƒ: แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒฃแƒš แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒแƒก แƒ›แƒแƒฃแƒฌแƒ”แƒ•แƒก แƒ‘แƒ”แƒ•แƒ แƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒ แƒ™แƒแƒœแƒขแƒ”แƒฅแƒกแƒขแƒฃแƒ แƒ˜ แƒ’แƒแƒ“แƒแƒกแƒ•แƒšแƒ”แƒ‘แƒ˜ ะธ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ”แƒ‘แƒ˜. แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒซแƒ•แƒ˜แƒ แƒแƒ“แƒฆแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ แƒ“แƒ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ˜แƒฌแƒ•แƒ˜แƒแƒก แƒ—แƒแƒ•แƒ˜แƒกแƒฃแƒคแƒแƒšแƒ˜ RAM-แƒ˜แƒก แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒแƒ‘แƒ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ—แƒแƒ›แƒ‘แƒ”แƒญแƒ“แƒแƒ•แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒ—.

แƒจแƒ”แƒชแƒ•แƒšแƒ˜แƒšแƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒฎแƒแƒ–แƒก แƒฃแƒกแƒ•แƒแƒ›แƒก แƒซแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒคแƒ˜แƒฅแƒกแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ (thread pool), แƒ แƒ˜แƒ—แƒแƒช แƒฎแƒ”แƒšแƒก แƒฃแƒจแƒšแƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฌแƒงแƒ•แƒ”แƒขแƒแƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒ›แƒแƒ•แƒ“แƒ แƒแƒฃแƒšแƒแƒ“ แƒจแƒ”แƒ›แƒแƒแƒฅแƒ•แƒก แƒแƒฎแƒแƒšแƒ˜ แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ: แƒ—แƒฃ thread pool แƒแƒ›แƒŸแƒแƒ›แƒแƒ“ แƒ“แƒแƒ‘แƒšแƒแƒ™แƒ˜แƒšแƒ˜แƒ แƒฎแƒแƒœแƒ’แƒ แƒซแƒšแƒ˜แƒ•แƒ˜ แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ—, แƒ›แƒแƒจแƒ˜แƒœ แƒกแƒฎแƒ•แƒ แƒกแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒกแƒแƒช แƒฃแƒ™แƒ•แƒ” แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ, แƒ•แƒ”แƒ  แƒจแƒ”แƒซแƒšแƒ”แƒ‘แƒ”แƒœ. แƒแƒกแƒ” แƒ’แƒแƒแƒ™แƒ”แƒ—แƒ”.

แƒ›แƒ”แƒแƒ แƒ” แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ (แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒกแƒ”แƒšแƒ”แƒฅแƒขแƒแƒ แƒ˜) แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ OS-แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ . แƒ”แƒก แƒกแƒขแƒแƒขแƒ˜แƒ แƒ’แƒแƒœแƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ แƒฉแƒ”แƒ•แƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒ’แƒแƒ•แƒ แƒชแƒ”แƒšแƒ”แƒ‘แƒฃแƒš แƒขแƒ˜แƒžแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ’แƒแƒคแƒ แƒ—แƒฎแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ–แƒ” (แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ”, แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ–แƒ”) I/O แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ›แƒ–แƒแƒ“แƒงแƒแƒคแƒœแƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ“แƒ แƒแƒ แƒ แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒ›แƒแƒ—แƒ˜ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘. แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒฌแƒแƒ แƒ›แƒแƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜ แƒ˜แƒงแƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒ‘แƒšแƒแƒ™-แƒกแƒฅแƒ”แƒ›แƒ˜แƒ—:

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒ แƒแƒ› แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜แƒ:

  • I/O แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ‘แƒšแƒแƒ™แƒ˜แƒ แƒ”แƒ‘แƒ แƒจแƒ”แƒแƒฉแƒ”แƒ แƒแƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒœแƒแƒ™แƒแƒ“แƒ˜ แƒ›แƒแƒœแƒแƒ›แƒ“แƒ”แƒกแƒแƒœแƒแƒ› OS แƒ’แƒแƒ›แƒแƒ แƒ—แƒฃแƒšแƒ˜แƒ แƒ“แƒ”แƒคแƒ แƒแƒ’แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ IP แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜ แƒ‘แƒแƒ˜แƒขแƒ˜แƒก แƒœแƒแƒ™แƒแƒ“แƒแƒ“ (TCP, แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ) แƒแƒœ แƒแƒ  แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜ แƒแƒ“แƒ’แƒ˜แƒšแƒ˜ แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒจแƒ˜แƒ“แƒ แƒ‘แƒฃแƒคแƒ”แƒ แƒ”แƒ‘แƒจแƒ˜ แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก NIC (แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ).
  • แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ›แƒ แƒฉแƒ”แƒ•แƒ˜ แƒ“แƒ แƒแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ แƒแƒชแƒœแƒแƒ‘แƒ”แƒ‘แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒแƒก, แƒ แƒแƒ› OS แƒฃแƒ™แƒ•แƒ” แƒ“แƒ”แƒคแƒ แƒแƒ’แƒ›แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ IP แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜ (TCP, แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ) แƒแƒœ แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜ แƒแƒ“แƒ’แƒ˜แƒšแƒ˜ แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒจแƒ˜แƒ“แƒ แƒ‘แƒฃแƒคแƒ”แƒ แƒ”แƒ‘แƒจแƒ˜ แƒฃแƒ™แƒ•แƒ” แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜ (แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ).

แƒ แƒแƒ› แƒจแƒ”แƒ•แƒแƒฏแƒแƒ›แƒแƒ—, OS-แƒ˜แƒก แƒซแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒฏแƒแƒ•แƒจแƒœแƒ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ I/O-แƒกแƒ—แƒ•แƒ˜แƒก แƒแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ—แƒ•แƒšแƒ˜แƒ—แƒ˜ แƒกแƒ˜แƒ›แƒซแƒšแƒแƒ•แƒ แƒ˜แƒก แƒ“แƒแƒ™แƒแƒ แƒ’แƒ•แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒกแƒ˜แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒ”แƒจแƒ˜, แƒซแƒแƒคแƒ”แƒ‘แƒ˜ แƒแƒ  แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ”แƒœ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒก (แƒแƒฅแƒ”แƒ“แƒแƒœ แƒ›แƒแƒ“แƒ˜แƒก แƒ”แƒก แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒ˜ "แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒฃแƒšแƒ˜ แƒจแƒ”แƒคแƒ”แƒ แƒฎแƒ”แƒ‘แƒ"). แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒกแƒ”แƒšแƒ”แƒฅแƒขแƒแƒ แƒ˜ แƒฌแƒงแƒ•แƒ”แƒขแƒก แƒแƒ› แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒแƒก, แƒ แƒแƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒแƒซแƒšแƒ”แƒ•แƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒแƒก แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒก CPU แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ”แƒ‘แƒ˜ แƒ‘แƒ”แƒ•แƒ แƒแƒ“ แƒฃแƒคแƒ แƒ แƒ”แƒ™แƒแƒœแƒแƒ›แƒ˜แƒฃแƒ แƒแƒ“.

I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒ›แƒแƒ“แƒ”แƒšแƒ˜

I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒก แƒ แƒแƒ’แƒแƒ แƒช แƒคแƒ”แƒœแƒ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ›แƒ แƒฉแƒ”แƒ•แƒ”แƒšแƒกแƒ แƒ“แƒ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒ™แƒแƒ“แƒก แƒจแƒแƒ แƒ˜แƒก. แƒ›แƒ˜แƒกแƒ˜ แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒ‘แƒšแƒแƒ™-แƒกแƒฅแƒ”แƒ›แƒ˜แƒ—:

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

  • แƒจแƒ”แƒ’แƒแƒฎแƒกแƒ”แƒœแƒ”แƒ‘แƒ—, แƒ แƒแƒ› แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ แƒแƒ แƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ แƒ˜แƒ›แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘, แƒ แƒแƒ› แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒš แƒกแƒแƒ™แƒ”แƒขแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒจแƒ”แƒแƒกแƒ แƒฃแƒšแƒแƒก แƒแƒ แƒแƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ˜แƒก I/O แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ.
  • แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒแƒ แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒ˜แƒซแƒแƒฎแƒ˜แƒก I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒก แƒแƒ แƒแƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ˜แƒก I/O แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒแƒก.

แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜แƒ แƒแƒฆแƒ˜แƒœแƒ˜แƒจแƒœแƒแƒก, แƒ แƒแƒ› I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜, แƒ’แƒแƒœแƒกแƒแƒ–แƒฆแƒ•แƒ แƒ”แƒ‘แƒ˜แƒ—, แƒแƒ แƒ˜แƒก แƒ”แƒ แƒ—แƒซแƒแƒคแƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒ แƒแƒคแƒ”แƒ แƒ˜ แƒฃแƒจแƒšแƒ˜แƒก แƒฎแƒ”แƒšแƒก แƒ™แƒแƒœแƒชแƒ”แƒคแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒแƒก แƒ›แƒ แƒแƒ•แƒแƒš แƒซแƒแƒคแƒ˜แƒแƒœ แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜ 1 แƒซแƒแƒคแƒ˜แƒก: 1 แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒ—แƒแƒœแƒแƒคแƒแƒ แƒ“แƒแƒ‘แƒ˜แƒ—, แƒ แƒ˜แƒ—แƒแƒช แƒ’แƒแƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ“แƒ”แƒ‘แƒ แƒงแƒ•แƒ”แƒšแƒ CPU แƒ‘แƒ˜แƒ แƒ—แƒ•แƒ˜.

ะ ะตะฐะปะธะทะฐั†ะธั

แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒœแƒ•แƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ— แƒกแƒแƒฏแƒแƒ แƒ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒก แƒคแƒแƒ˜แƒšแƒจแƒ˜ reactor.h, แƒ“แƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ - แƒจแƒ”แƒ›แƒแƒกแƒฃแƒšแƒ˜ reactor.c. reactor.h แƒจแƒ”แƒ“แƒ’แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒ’แƒแƒœแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒกแƒแƒ’แƒแƒœ:

แƒ“แƒ”แƒ™แƒšแƒแƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒจแƒ˜.h

typedef struct reactor Reactor;

/*
 * ะฃะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ั„ัƒะฝะบั†ะธัŽ, ะบะพั‚ะพั€ะฐั ะฑัƒะดะตั‚ ะฒั‹ะทั‹ะฒะฐั‚ัŒัั I/O ั€ะตะฐะบั‚ะพั€ะพะผ ะฟั€ะธ ะฟะพัั‚ัƒะฟะปะตะฝะธะธ
 * ัะพะฑั‹ั‚ะธั ะพั‚ ัะธัั‚ะตะผะฝะพะณะพ ัะตะปะตะบั‚ะพั€ะฐ.
 */
typedef void (*Callback)(void *arg, int fd, uint32_t events);

/*
 * ะ’ะพะทะฒั€ะฐั‰ะฐะตั‚ `NULL` ะฒ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ, ะฝะต-`NULL` ัƒะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ `Reactor` ะฒ
 * ะฟั€ะพั‚ะธะฒะฝะพะผ ัะปัƒั‡ะฐะต.
 */
Reactor *reactor_new(void);

/*
 * ะžัะฒะพะฑะพะถะดะฐะตั‚ ัะธัั‚ะตะผะฝั‹ะน ัะตะปะตะบั‚ะพั€, ะฒัะต ะทะฐั€ะตะณะธัั‚ั€ะธั€ะพะฒะฐะฝะฝั‹ะต ัะพะบะตั‚ั‹ ะฒ ะดะฐะฝะฝั‹ะน ะผะพะผะตะฝั‚
 * ะฒั€ะตะผะตะฝะธ ะธ ัะฐะผ I/O ั€ะตะฐะบั‚ะพั€.
 *
 * ะกะปะตะดัƒัŽั‰ะธะต ั„ัƒะฝะบั†ะธะธ ะฒะพะทะฒั€ะฐั‰ะฐัŽั‚ -1 ะฒ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ, 0 ะฒ ัะปัƒั‡ะฐะต ัƒัะฟะตั…ะฐ.
 */
int reactor_destroy(Reactor *reactor);

int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
                     Callback callback, void *callback_arg);
int reactor_deregister(const Reactor *reactor, int fd);
int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
                       Callback callback, void *callback_arg);

/*
 * ะ—ะฐะฟัƒัะบะฐะตั‚ ั†ะธะบะป ัะพะฑั‹ั‚ะธะน ั ั‚ะฐะนะผ-ะฐัƒั‚ะพะผ `timeout`.
 *
 * ะญั‚ะฐ ั„ัƒะฝะบั†ะธั ะฟะตั€ะตะดะฐัั‚ ัƒะฟั€ะฐะฒะปะตะฝะธะต ะฒั‹ะทั‹ะฒะฐัŽั‰ะตะผัƒ ะบะพะดัƒ ะตัะปะธ ะพั‚ะฒะตะดั‘ะฝะฝะพะต ะฒั€ะตะผั ะฒั‹ัˆะปะพ
 * ะธะปะธ/ะธ ะฟั€ะธ ะพั‚ััƒั‚ัั‚ะฒะธะธ ะทะฐั€ะตะณะธัั‚ั€ะธั€ะพะฒะฐะฝะฝั‹ั… ัะพะบะตั‚ะพะฒ.
 */
int reactor_run(const Reactor *reactor, time_t timeout);

I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ แƒจแƒ”แƒ“แƒ’แƒ”แƒ‘แƒ แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒแƒฆแƒ›แƒฌแƒ”แƒ แƒ˜ แƒกแƒ”แƒšแƒ”แƒฅแƒขแƒแƒ แƒ˜ แƒ”แƒžแƒแƒšแƒ˜ ะธ แƒฐแƒ”แƒจแƒ˜แƒก แƒชแƒฎแƒ แƒ˜แƒšแƒ”แƒ‘แƒ˜ GHashTable, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒกแƒแƒฎแƒแƒ•แƒก แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒกแƒแƒ™แƒ”แƒขแƒก CallbackData (แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒšแƒ˜แƒก แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ แƒ“แƒ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ˜ แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก).

Reactor-แƒ˜แƒกแƒ แƒ“แƒ CallbackData-แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

struct reactor {
    int epoll_fd;
    GHashTable *table; // (int, CallbackData)
};

typedef struct {
    Callback callback;
    void *arg;
} CallbackData;

แƒ’แƒ—แƒฎแƒแƒ•แƒ— แƒ’แƒแƒ˜แƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒแƒ—, แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ•แƒแƒแƒฅแƒขแƒ˜แƒฃแƒ แƒ”แƒ— แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ แƒแƒ แƒแƒกแƒ แƒฃแƒšแƒ˜ แƒขแƒ˜แƒžแƒ˜ แƒ˜แƒœแƒ“แƒ”แƒฅแƒกแƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—. IN reactor.h แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒชแƒฎแƒแƒ“แƒ”แƒ‘แƒ— แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒแƒก reactorแƒ“แƒ reactor.c แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒœแƒ•แƒกแƒแƒ–แƒฆแƒ•แƒ แƒแƒ•แƒ— แƒ›แƒแƒก, แƒ แƒ˜แƒ—แƒแƒช แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒก แƒฎแƒ”แƒšแƒก แƒฃแƒจแƒšแƒ˜แƒก แƒ›แƒ˜แƒกแƒ˜ แƒ•แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒชแƒแƒšแƒกแƒแƒฎแƒแƒ“ แƒจแƒ”แƒชแƒ•แƒšแƒแƒจแƒ˜. แƒ”แƒก แƒแƒ แƒ˜แƒก แƒ”แƒ แƒ—-แƒ”แƒ แƒ—แƒ˜ แƒœแƒ˜แƒ›แƒฃแƒจแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒแƒšแƒ•แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒšแƒแƒ™แƒแƒœแƒฃแƒ แƒแƒ“ แƒฏแƒ“แƒ”แƒ‘แƒ C แƒกแƒ”แƒ›แƒแƒœแƒขแƒ˜แƒ™แƒแƒจแƒ˜.

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜ reactor_register, reactor_deregister ะธ reactor_reregister แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒ”แƒ— แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒกแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ แƒ“แƒ แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒ˜ แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ›แƒ แƒฉแƒ”แƒ•แƒ”แƒšแƒจแƒ˜ แƒ“แƒ แƒฐแƒ”แƒจแƒ˜แƒก แƒชแƒฎแƒ แƒ˜แƒšแƒจแƒ˜.

แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

#define REACTOR_CTL(reactor, op, fd, interest)                                 
    if (epoll_ctl(reactor->epoll_fd, op, fd,                                   
                  &(struct epoll_event){.events = interest,                    
                                        .data = {.fd = fd}}) == -1) {          
        perror("epoll_ctl");                                                   
        return -1;                                                             
    }

int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
                     Callback callback, void *callback_arg) {
    REACTOR_CTL(reactor, EPOLL_CTL_ADD, fd, interest)
    g_hash_table_insert(reactor->table, int_in_heap(fd),
                        callback_data_new(callback, callback_arg));
    return 0;
}

int reactor_deregister(const Reactor *reactor, int fd) {
    REACTOR_CTL(reactor, EPOLL_CTL_DEL, fd, 0)
    g_hash_table_remove(reactor->table, &fd);
    return 0;
}

int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
                       Callback callback, void *callback_arg) {
    REACTOR_CTL(reactor, EPOLL_CTL_MOD, fd, interest)
    g_hash_table_insert(reactor->table, int_in_heap(fd),
                        callback_data_new(callback, callback_arg));
    return 0;
}

แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒฉแƒแƒญแƒ แƒแƒก แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒ— fd, แƒ˜แƒก แƒฃแƒฌแƒแƒ“แƒ”แƒ‘แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒก แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒช แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒก fd, แƒชแƒแƒขแƒ แƒœแƒ˜แƒฆแƒแƒ‘แƒ˜ แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒ›แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ”แƒšแƒ˜ void.

reactor_run() แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

int reactor_run(const Reactor *reactor, time_t timeout) {
    int result;
    struct epoll_event *events;
    if ((events = calloc(MAX_EVENTS, sizeof(*events))) == NULL)
        abort();

    time_t start = time(NULL);

    while (true) {
        time_t passed = time(NULL) - start;
        int nfds =
            epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, timeout - passed);

        switch (nfds) {
        // ะžัˆะธะฑะบะฐ
        case -1:
            perror("epoll_wait");
            result = -1;
            goto cleanup;
        // ะ’ั€ะตะผั ะฒั‹ัˆะปะพ
        case 0:
            result = 0;
            goto cleanup;
        // ะฃัะฟะตัˆะฝะฐั ะพะฟะตั€ะฐั†ะธั
        default:
            // ะ’ั‹ะทะฒะฐั‚ัŒ ะพะฑั€ะฐะฑะพั‚ั‡ะธะบะพะฒ ัะพะฑั‹ั‚ะธะน
            for (int i = 0; i < nfds; i++) {
                int fd = events[i].data.fd;

                CallbackData *callback =
                    g_hash_table_lookup(reactor->table, &fd);
                callback->callback(callback->arg, fd, events[i].events);
            }
        }
    }

cleanup:
    free(events);
    return result;
}

แƒจแƒ”แƒฏแƒแƒ›แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒ™แƒแƒ“แƒจแƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ˜แƒก แƒฏแƒแƒญแƒ•แƒ˜ แƒ›แƒ˜แƒ˜แƒฆแƒ”แƒ‘แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒคแƒแƒ แƒ›แƒแƒก:

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒ”แƒ แƒ—แƒ˜ แƒฎแƒ แƒแƒฎแƒœแƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜

แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ— I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒ›แƒแƒฆแƒแƒšแƒ˜ แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ— แƒ›แƒแƒ แƒขแƒ˜แƒ• HTTP แƒ•แƒ”แƒ‘ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒžแƒแƒกแƒฃแƒฎแƒแƒ‘แƒก แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ  แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒ—.

แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒ HTTP แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ–แƒ”

HTTP - แƒ”แƒก แƒแƒ แƒ˜แƒก แƒแƒฅแƒ›แƒ˜ แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ˜แƒก แƒ“แƒแƒœแƒ”, แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒแƒ“ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ -แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜แƒก แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

HTTP แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ“ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ˜แƒฅแƒœแƒแƒก แƒขแƒ แƒแƒœแƒกแƒžแƒแƒ แƒขแƒ˜ แƒแƒฅแƒ›แƒ˜ TCP, แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ แƒ“แƒ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒคแƒแƒ แƒ›แƒแƒขแƒ˜แƒ— แƒกแƒžแƒ”แƒชแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ.

แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒคแƒแƒ แƒ›แƒแƒขแƒ˜

<ะšะžะœะะะ”ะ> <URI> <ะ’ะ•ะ ะกะ˜ะฏ HTTP>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 1>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 2>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš N>CRLF CRLF
<ะ”ะะะะซะ•>

  • CRLF แƒแƒ แƒ˜แƒก แƒแƒ แƒ˜ แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒแƒก แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒแƒ‘แƒ: r ะธ n, แƒ’แƒแƒ›แƒแƒงแƒแƒคแƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒก, แƒกแƒแƒ—แƒแƒฃแƒ แƒ”แƒ‘แƒก แƒ“แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒก.
  • <ะšะžะœะะะ”ะ> - แƒ”แƒ แƒ— - แƒ”แƒ แƒ—แƒ˜ CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE. แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜ แƒ’แƒแƒ›แƒแƒ’แƒ˜แƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒ— แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒแƒก แƒฉแƒ•แƒ”แƒœแƒก แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” GET, แƒ แƒแƒช แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก "แƒ’แƒแƒ›แƒแƒ›แƒ˜แƒ’แƒ–แƒแƒ•แƒœแƒ” แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜."
  • <URI> - แƒ”แƒ แƒ—แƒ˜แƒแƒœแƒ˜ แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ˜แƒก แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜. แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ—แƒฃ URI = /index.html, แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜ แƒ˜แƒ—แƒฎแƒแƒ•แƒก แƒกแƒแƒ˜แƒขแƒ˜แƒก แƒ›แƒ—แƒแƒ•แƒแƒ  แƒ’แƒ•แƒ”แƒ แƒ“แƒก.
  • <ะ’ะ•ะ ะกะ˜ะฏ HTTP> โ€” HTTP แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜แƒก แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒคแƒแƒ แƒ›แƒแƒขแƒจแƒ˜ HTTP/X.Y. แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒฎแƒจแƒ˜แƒ แƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒ“แƒฆแƒ”แƒก แƒแƒ แƒ˜แƒก HTTP/1.1.
  • <ะ—ะะ“ะžะ›ะžะ’ะžะš N> แƒแƒ แƒ˜แƒก แƒ’แƒแƒกแƒแƒฆแƒ”แƒ‘แƒ˜-แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ˜แƒก แƒฌแƒงแƒ•แƒ˜แƒšแƒ˜ แƒคแƒแƒ แƒ›แƒแƒขแƒจแƒ˜ <ะšะ›ะฎะง>: <ะ—ะะะงะ•ะะ˜ะ•>, แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒšแƒ˜แƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒแƒœแƒแƒšแƒ˜แƒ–แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.
  • <ะ”ะะะะซะ•> โ€” แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒšแƒแƒ“ แƒกแƒแƒญแƒ˜แƒ แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜. แƒฎแƒจแƒ˜แƒ แƒแƒ“ แƒ”แƒก แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒ JSON แƒแƒœ แƒกแƒฎแƒ•แƒ แƒคแƒแƒ แƒ›แƒแƒขแƒจแƒ˜.

แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒก แƒคแƒแƒ แƒ›แƒแƒขแƒ˜

<ะ’ะ•ะ ะกะ˜ะฏ HTTP> <ะšะžะ” ะกะขะะขะฃะกะ> <ะžะŸะ˜ะกะะะ˜ะ• ะกะขะะขะฃะกะ>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 1>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 2>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš N>CRLF CRLF
<ะ”ะะะะซะ•>

  • <ะšะžะ” ะกะขะะขะฃะกะ> แƒแƒ แƒ˜แƒก แƒ แƒ˜แƒชแƒฎแƒ•แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฌแƒแƒ แƒ›แƒแƒแƒ“แƒ’แƒ”แƒœแƒก แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒก. แƒฉแƒ•แƒ”แƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒกแƒขแƒแƒขแƒฃแƒกแƒก 200 (แƒฌแƒแƒ แƒ›แƒแƒขแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ).
  • <ะžะŸะ˜ะกะะะ˜ะ• ะกะขะะขะฃะกะ> โ€” แƒกแƒขแƒแƒขแƒฃแƒกแƒ˜แƒก แƒ™แƒแƒ“แƒ˜แƒก แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜แƒก แƒฌแƒแƒ แƒ›แƒแƒ“แƒ’แƒ”แƒœแƒ. แƒกแƒขแƒแƒขแƒฃแƒกแƒ˜แƒก แƒ™แƒแƒ“แƒ˜ 200 แƒ”แƒก แƒแƒ แƒ˜แƒก OK.
  • <ะ—ะะ“ะžะ›ะžะ’ะžะš N> - แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒคแƒแƒ แƒ›แƒแƒขแƒ˜แƒก แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜. แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒ— แƒขแƒ˜แƒขแƒฃแƒšแƒ”แƒ‘แƒก Content-Length (แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒ–แƒแƒ›แƒ) แƒ“แƒ Content-Type: text/html (แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒขแƒ˜แƒžแƒ˜).
  • <ะ”ะะะะซะ•> - แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒšแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜. แƒฉแƒ•แƒ”แƒœแƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ”แƒก แƒแƒ แƒ˜แƒก แƒ’แƒ–แƒ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒกแƒ™แƒ”แƒœ HTML.

แƒคแƒแƒ˜แƒšแƒ˜ http_server.c (แƒ”แƒ แƒ— แƒฎแƒ แƒแƒฎแƒœแƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜) แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒคแƒแƒ˜แƒšแƒก common.h, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒžแƒ แƒแƒขแƒแƒขแƒ˜แƒžแƒ”แƒ‘แƒก:

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒžแƒ แƒแƒขแƒแƒขแƒ˜แƒžแƒ”แƒ‘แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ แƒกแƒแƒ”แƒ แƒ—แƒ.h

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะฟั€ะธะฝัั‚ัŒ ะฝะพะฒะพะต ัะพะตะดะธะฝะตะฝะธะต.
 */
static void on_accept(void *arg, int fd, uint32_t events);

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะพั‚ะฟั€ะฐะฒะธั‚ัŒ HTTP ะพั‚ะฒะตั‚.
 */
static void on_send(void *arg, int fd, uint32_t events);

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะฟั€ะธะฝัั‚ัŒ ั‡ะฐัั‚ัŒ HTTP ะทะฐะฟั€ะพัะฐ.
 */
static void on_recv(void *arg, int fd, uint32_t events);

/*
 * ะŸะตั€ะตะฒะพะดะธั‚ ะฒั…ะพะดัั‰ะตะต ัะพะตะดะธะฝะตะฝะธะต ะฒ ะฝะตะฑะปะพะบะธั€ัƒัŽั‰ะธะน ั€ะตะถะธะผ.
 */
static void set_nonblocking(int fd);

/*
 * ะŸะตั‡ะฐั‚ะฐะตั‚ ะฟะตั€ะตะดะฐะฝะฝั‹ะต ะฐั€ะณัƒะผะตะฝั‚ั‹ ะฒ stderr ะธ ะฒั‹ั…ะพะดะธั‚ ะธะท ะฟั€ะพั†ะตััะฐ ั
 * ะบะพะดะพะผ `EXIT_FAILURE`.
 */
static noreturn void fail(const char *format, ...);

/*
 * ะ’ะพะทะฒั€ะฐั‰ะฐะตั‚ ั„ะฐะนะปะพะฒั‹ะน ะดะตัะบั€ะธะฟั‚ะพั€ ัะพะบะตั‚ะฐ, ัะฟะพัะพะฑะฝะพะณะพ ะฟั€ะธะฝะธะผะฐั‚ัŒ ะฝะพะฒั‹ะต
 * TCP ัะพะตะดะธะฝะตะฝะธั.
 */
static int new_server(bool reuse_port);

แƒแƒกแƒ”แƒ•แƒ” แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒฃแƒ แƒ˜ แƒ›แƒแƒ™แƒ แƒ SAFE_CALL() แƒ“แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ’แƒแƒœแƒ˜แƒกแƒแƒ–แƒฆแƒ•แƒ แƒ”แƒ‘แƒ fail(). แƒ›แƒแƒ™แƒ แƒ แƒ’แƒแƒ›แƒแƒฎแƒแƒขแƒ•แƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒแƒก แƒแƒ“แƒแƒ แƒ”แƒ‘แƒก แƒจแƒ”แƒชแƒ“แƒแƒ›แƒแƒก แƒ“แƒ แƒ—แƒฃ แƒžแƒ˜แƒ แƒแƒ‘แƒ trueแƒ, แƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒก fail():

#define SAFE_CALL(call, error)                                                 
    do {                                                                       
        if ((call) == error) {                                                   
            fail("%s", #call);                                                 
        }                                                                      
    } while (false)

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ fail() แƒ‘แƒ”แƒญแƒ“แƒแƒ•แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒฃแƒš แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒก แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒจแƒ˜ (แƒ แƒแƒ’แƒแƒ แƒช printf()) แƒ“แƒ แƒฌแƒงแƒ•แƒ”แƒขแƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒแƒก แƒ™แƒแƒ“แƒ˜แƒ— EXIT_FAILURE:

static noreturn void fail(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    fprintf(stderr, ": %sn", strerror(errno));
    exit(EXIT_FAILURE);
}

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ new_server() แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ–แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒš "แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก" แƒกแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒก socket(), bind() ะธ listen() แƒ“แƒ แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ แƒแƒ แƒแƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ˜แƒก แƒ แƒ”แƒŸแƒ˜แƒ›แƒจแƒ˜.

new_server() แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

static int new_server(bool reuse_port) {
    int fd;
    SAFE_CALL((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)),
              -1);

    if (reuse_port) {
        SAFE_CALL(
            setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int)),
            -1);
    }

    struct sockaddr_in addr = {.sin_family = AF_INET,
                               .sin_port = htons(SERVER_PORT),
                               .sin_addr = {.s_addr = inet_addr(SERVER_IPV4)},
                               .sin_zero = {0}};

    SAFE_CALL(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), -1);
    SAFE_CALL(listen(fd, SERVER_BACKLOG), -1);
    return fd;
}

  • แƒ’แƒแƒ˜แƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒ”แƒ—, แƒ แƒแƒ› แƒกแƒแƒ™แƒ”แƒขแƒ˜ แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒแƒ“ แƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ แƒแƒ แƒ-แƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ˜แƒก แƒ แƒ”แƒŸแƒ˜แƒ›แƒจแƒ˜ แƒ“แƒ แƒแƒจแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— SOCK_NONBLOCKแƒ˜แƒกแƒ” แƒ แƒแƒ› แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜ on_accept() (แƒ“แƒแƒฌแƒ•แƒ แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒ—) แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ–แƒแƒ แƒ˜ accept() แƒแƒ  แƒจแƒ”แƒฃแƒฌแƒงแƒ•แƒ”แƒขแƒ˜แƒ แƒซแƒแƒคแƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ.
  • แƒ—แƒฃ reuse_port แƒขแƒแƒšแƒ˜แƒ true, แƒ›แƒแƒจแƒ˜แƒœ แƒ”แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ“แƒแƒแƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒ”แƒ‘แƒก แƒกแƒแƒ™แƒ”แƒขแƒก แƒแƒคแƒชแƒ˜แƒ˜แƒ— SO_REUSEPORT แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ— setsockopt()แƒ”แƒ แƒ—แƒ˜ แƒ“แƒ แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒžแƒแƒ แƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ›แƒ แƒแƒ•แƒแƒš แƒฎแƒ แƒแƒฎแƒœแƒ˜แƒแƒœ แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜ (แƒ˜แƒฎ. แƒกแƒ”แƒฅแƒชแƒ˜แƒ โ€žแƒ›แƒ แƒแƒ•แƒแƒšแƒœแƒแƒ™แƒแƒ“แƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜โ€œ).

แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜ on_accept() แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช OS แƒฌแƒแƒ แƒ›แƒแƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒแƒ•แƒšแƒ”แƒœแƒแƒก EPOLLIN, แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ. on_accept() แƒ˜แƒฆแƒ”แƒ‘แƒก แƒแƒฎแƒแƒš แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒก, แƒ’แƒแƒ“แƒแƒ แƒ—แƒแƒ•แƒก แƒ›แƒแƒก แƒแƒ แƒแƒ“แƒแƒ‘แƒšแƒแƒ™แƒ•แƒ˜แƒก แƒ แƒ”แƒŸแƒ˜แƒ›แƒจแƒ˜ แƒ“แƒ แƒ“แƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ—แƒแƒœ on_recv() I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒจแƒ˜.

on_accept() แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

static void on_accept(void *arg, int fd, uint32_t events) {
    int incoming_conn;
    SAFE_CALL((incoming_conn = accept(fd, NULL, NULL)), -1);
    set_nonblocking(incoming_conn);
    SAFE_CALL(reactor_register(reactor, incoming_conn, EPOLLIN, on_recv,
                               request_buffer_new()),
              -1);
}

แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜ on_recv() แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช OS แƒฌแƒแƒ แƒ›แƒแƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒแƒ•แƒšแƒ”แƒœแƒแƒก EPOLLIN, แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜ แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ on_accept(), แƒ›แƒ–แƒแƒ“ แƒแƒ แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒฆแƒ”แƒ‘แƒแƒ“.

on_recv() แƒ™แƒ˜แƒ—แƒฎแƒฃแƒšแƒแƒ‘แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒก แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒ“แƒแƒœ HTTP แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒกแƒ แƒฃแƒšแƒแƒ“ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒแƒ›แƒ“แƒ”, แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ“แƒแƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ”แƒ‘แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒก on_send() HTTP แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒก แƒ’แƒแƒกแƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ“. แƒ—แƒฃ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜ แƒแƒ แƒฆแƒ•แƒ”แƒ•แƒก แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒก, แƒกแƒแƒ™แƒ”แƒขแƒ˜ แƒ’แƒแƒฃแƒฅแƒ›แƒ“แƒ”แƒ‘แƒ แƒ“แƒ แƒ˜แƒฎแƒฃแƒ แƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— close().

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ on_recv()

static void on_recv(void *arg, int fd, uint32_t events) {
    RequestBuffer *buffer = arg;

    // ะŸั€ะธะฝะธะผะฐะตะผ ะฒั…ะพะดะฝั‹ะต ะดะฐะฝะฝั‹ะต ะดะพ ั‚ะตั… ะฟะพั€, ั‡ั‚ะพ recv ะฒะพะทะฒั€ะฐั‚ะธั‚ 0 ะธะปะธ ะพัˆะธะฑะบัƒ
    ssize_t nread;
    while ((nread = recv(fd, buffer->data + buffer->size,
                         REQUEST_BUFFER_CAPACITY - buffer->size, 0)) > 0)
        buffer->size += nread;

    // ะšะปะธะตะฝั‚ ะพะฑะพั€ะฒะฐะป ัะพะตะดะธะฝะตะฝะธะต
    if (nread == 0) {
        SAFE_CALL(reactor_deregister(reactor, fd), -1);
        SAFE_CALL(close(fd), -1);
        request_buffer_destroy(buffer);
        return;
    }

    // read ะฒะตั€ะฝัƒะป ะพัˆะธะฑะบัƒ, ะพั‚ะปะธั‡ะฝัƒัŽ ะพั‚ ะพัˆะธะฑะบะธ, ะฟั€ะธ ะบะพั‚ะพั€ะพะน ะฒั‹ะทะพะฒ ะทะฐะฑะปะพะบะธั€ัƒะตั‚
    // ะฟะพั‚ะพะบ
    if (errno != EAGAIN && errno != EWOULDBLOCK) {
        request_buffer_destroy(buffer);
        fail("read");
    }

    // ะŸะพะปัƒั‡ะตะฝ ะฟะพะปะฝั‹ะน HTTP ะทะฐะฟั€ะพั ะพั‚ ะบะปะธะตะฝั‚ะฐ. ะขะตะฟะตั€ัŒ ั€ะตะณะธัั‚ั€ะธั€ัƒะตะผ ะพะฑั€ะฐะฑะพั‚ั‡ะธะบะฐ
    // ัะพะฑั‹ั‚ะธะน ะดะปั ะพั‚ะฟั€ะฐะฒะบะธ ะดะฐะฝะฝั‹ั…
    if (request_buffer_is_complete(buffer)) {
        request_buffer_clear(buffer);
        SAFE_CALL(reactor_reregister(reactor, fd, EPOLLOUT, on_send, buffer),
                  -1);
    }
}

แƒฆแƒแƒœแƒ˜แƒกแƒซแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜ on_send() แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช OS แƒฌแƒแƒ แƒ›แƒแƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒแƒ•แƒšแƒ”แƒœแƒแƒก EPOLLOUT, แƒ แƒแƒช แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜ แƒ“แƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ“แƒ on_recv(), แƒ›แƒ–แƒแƒ“ แƒแƒ แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒกแƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ“. แƒ”แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒก แƒฃแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒก HTTP แƒžแƒแƒกแƒฃแƒฎแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก HTML แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒแƒก แƒ“แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒชแƒ•แƒšแƒ˜แƒก แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒก. on_recv().

on_send() แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ

static void on_send(void *arg, int fd, uint32_t events) {
    const char *content = "<img "
                          "src="https://habrastorage.org/webt/oh/wl/23/"
                          "ohwl23va3b-dioerobq_mbx4xaw.jpeg">";
    char response[1024];
    sprintf(response,
            "HTTP/1.1 200 OK" CRLF "Content-Length: %zd" CRLF "Content-Type: "
            "text/html" DOUBLE_CRLF "%s",
            strlen(content), content);

    SAFE_CALL(send(fd, response, strlen(response), 0), -1);
    SAFE_CALL(reactor_reregister(reactor, fd, EPOLLIN, on_recv, arg), -1);
}

แƒ“แƒ แƒ‘แƒแƒšแƒแƒก, แƒคแƒแƒ˜แƒšแƒจแƒ˜ http_server.c, แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜ main() แƒฉแƒ•แƒ”แƒœ แƒ•แƒฅแƒ›แƒœแƒ˜แƒ— I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— reactor_new()แƒจแƒ”แƒฅแƒ›แƒ”แƒœแƒ˜แƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒกแƒแƒ™แƒ”แƒขแƒ˜ แƒ“แƒ แƒ“แƒแƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ”แƒ— แƒ˜แƒ’แƒ˜, แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ— แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ reactor_run() แƒ–แƒฃแƒกแƒขแƒแƒ“ แƒ”แƒ แƒ—แƒ˜ แƒฌแƒฃแƒ—แƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜, แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ™แƒ˜ แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ”แƒ‘แƒก แƒ•แƒแƒ—แƒแƒ•แƒ˜แƒกแƒฃแƒคแƒšแƒ”แƒ‘แƒ— แƒ“แƒ แƒ’แƒแƒ›แƒแƒ•แƒ“แƒ˜แƒ•แƒแƒ แƒ— แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒ“แƒแƒœ.

แƒแƒฉแƒ•แƒ”แƒœแƒ” http_server.c

#include "reactor.h"

static Reactor *reactor;

#include "common.h"

int main(void) {
    SAFE_CALL((reactor = reactor_new()), NULL);
    SAFE_CALL(
        reactor_register(reactor, new_server(false), EPOLLIN, on_accept, NULL),
        -1);
    SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
    SAFE_CALL(reactor_destroy(reactor), -1);
}

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ—, แƒ แƒแƒ› แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒ˜แƒกแƒ”, แƒ แƒแƒ’แƒแƒ แƒช แƒ›แƒแƒกแƒแƒšแƒแƒ“แƒœแƒ”แƒšแƒ˜แƒ. แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ (chmod a+x compile.sh && ./compile.sh แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒก root-แƒจแƒ˜) แƒ“แƒ แƒ’แƒแƒฃแƒจแƒ•แƒ˜แƒ— แƒ—แƒ•แƒ˜แƒ—แƒœแƒแƒฌแƒ”แƒ แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜, แƒ’แƒแƒฎแƒกแƒ”แƒœแƒ˜แƒ— http://127.0.0.1:18470 แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒ“แƒ แƒœแƒแƒฎแƒ”แƒ— แƒ แƒแƒก แƒ•แƒ”แƒšแƒแƒ“แƒ˜แƒ—:

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ–แƒแƒ›แƒ•แƒ

แƒแƒฉแƒ•แƒ”แƒœแƒ” แƒฉแƒ”แƒ›แƒ˜ แƒ›แƒแƒœแƒฅแƒแƒœแƒ˜แƒก แƒกแƒžแƒ”แƒชแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜

$ screenfetch
 MMMMMMMMMMMMMMMMMMMMMMMMMmds+.        OS: Mint 19.1 tessa
 MMm----::-://////////////oymNMd+`     Kernel: x86_64 Linux 4.15.0-20-generic
 MMd      /++                -sNMd:    Uptime: 2h 34m
 MMNso/`  dMM    `.::-. .-::.` .hMN:   Packages: 2217
 ddddMMh  dMM   :hNMNMNhNMNMNh: `NMm   Shell: bash 4.4.20
     NMm  dMM  .NMN/-+MMM+-/NMN` dMM   Resolution: 1920x1080
     NMm  dMM  -MMm  `MMM   dMM. dMM   DE: Cinnamon 4.0.10
     NMm  dMM  -MMm  `MMM   dMM. dMM   WM: Muffin
     NMm  dMM  .mmd  `mmm   yMM. dMM   WM Theme: Mint-Y-Dark (Mint-Y)
     NMm  dMM`  ..`   ...   ydm. dMM   GTK Theme: Mint-Y [GTK2/3]
     hMM- +MMd/-------...-:sdds  dMM   Icon Theme: Mint-Y
     -NMm- :hNMNNNmdddddddddy/`  dMM   Font: Noto Sans 9
      -dMNs-``-::::-------.``    dMM   CPU: Intel Core i7-6700 @ 8x 4GHz [52.0ยฐC]
       `/dMNmy+/:-------------:/yMMM   GPU: NV136
          ./ydNMMMMMMMMMMMMMMMMMMMMM   RAM: 2544MiB / 7926MiB
             .MMMMMMMMMMMMMMMMMMM

แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ•แƒ–แƒแƒ›แƒแƒ— แƒ”แƒ แƒ—แƒ˜ แƒฎแƒ แƒแƒฎแƒœแƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ. แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ•แƒฎแƒกแƒœแƒแƒ— แƒแƒ แƒ˜ แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒ˜: แƒ”แƒ แƒ—แƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ— ./http_server, แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒแƒ“ - แƒ›แƒ™แƒ•แƒ“แƒแƒ แƒ˜. แƒ”แƒ แƒ—แƒ˜ แƒฌแƒฃแƒ—แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒกแƒขแƒ˜แƒ™แƒ แƒ’แƒแƒ›แƒแƒฉแƒœแƒ“แƒ”แƒ‘แƒ แƒ›แƒ”แƒแƒ แƒ” แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒจแƒ˜:

$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   493.52us   76.70us  17.31ms   89.57%
    Req/Sec    24.37k     1.81k   29.34k    68.13%
  11657769 requests in 1.00m, 1.60GB read
Requests/sec: 193974.70
Transfer/sec:     27.19MB

แƒฉแƒ•แƒ”แƒœแƒ›แƒ แƒ”แƒ แƒ—แƒœแƒแƒ™แƒแƒ“แƒ˜แƒแƒœ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒก แƒจแƒ”แƒ”แƒซแƒšแƒ แƒฌแƒฃแƒ—แƒจแƒ˜ 11 แƒ›แƒ˜แƒšแƒ˜แƒแƒœแƒ–แƒ” แƒ›แƒ”แƒขแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ 100 แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒ“แƒแƒœ. แƒแƒ  แƒแƒ แƒ˜แƒก แƒชแƒฃแƒ“แƒ˜ แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ—แƒฃ แƒแƒ แƒ แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒฃแƒ›แƒฏแƒแƒ‘แƒ”แƒกแƒ”แƒ‘แƒ?

แƒ›แƒ แƒแƒ•แƒแƒšแƒซแƒแƒคแƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜

แƒ แƒแƒ’แƒแƒ แƒช แƒ–แƒ”แƒ›แƒแƒ— แƒแƒฆแƒ˜แƒœแƒ˜แƒจแƒœแƒ, I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒจแƒ”แƒ˜แƒฅแƒ›แƒœแƒแƒก แƒชแƒแƒšแƒ™แƒ”แƒฃแƒš แƒซแƒแƒคแƒ”แƒ‘แƒจแƒ˜, แƒ แƒ˜แƒ—แƒแƒช แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก แƒงแƒ•แƒ”แƒšแƒ CPU แƒ‘แƒ˜แƒ แƒ—แƒ•แƒก. แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ”แƒก แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ แƒžแƒ แƒแƒฅแƒขแƒ˜แƒ™แƒแƒจแƒ˜:

แƒแƒฉแƒ•แƒ”แƒœแƒ” http_server_multithreaded.c

#include "reactor.h"

static Reactor *reactor;
#pragma omp threadprivate(reactor)

#include "common.h"

int main(void) {
#pragma omp parallel
    {
        SAFE_CALL((reactor = reactor_new()), NULL);
        SAFE_CALL(reactor_register(reactor, new_server(true), EPOLLIN,
                                   on_accept, NULL),
                  -1);
        SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
        SAFE_CALL(reactor_destroy(reactor), -1);
    }
}

แƒแƒฎแƒšแƒ แƒงแƒ•แƒ”แƒšแƒ แƒ—แƒ”แƒ›แƒ แƒคแƒšแƒแƒ‘แƒก แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒก แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜:

static Reactor *reactor;
#pragma omp threadprivate(reactor)

แƒ’แƒ—แƒฎแƒแƒ•แƒ— แƒ’แƒแƒ˜แƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒแƒ—, แƒ แƒแƒ› แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ˜ new_server() แƒแƒ“แƒ•แƒแƒ™แƒแƒขแƒ”แƒ‘แƒก true. แƒ”แƒก แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒซแƒšแƒ”แƒ•แƒ— แƒแƒคแƒชแƒ˜แƒแƒก แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒกแƒแƒ™แƒ”แƒขแƒก SO_REUSEPORTแƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒก แƒ˜แƒ’แƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒซแƒแƒคแƒ˜แƒแƒœ แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜. แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒแƒ— แƒ›แƒ”แƒขแƒ˜ แƒ“แƒ”แƒขแƒแƒšแƒ˜ แƒแƒฅ.

แƒ›แƒ”แƒแƒ แƒ” แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ

แƒแƒฎแƒšแƒ แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ•แƒ–แƒแƒ›แƒแƒ— แƒ›แƒ แƒแƒ•แƒแƒšแƒœแƒแƒ™แƒแƒ“แƒ˜แƒแƒœแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ:

$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.14ms    2.53ms  40.73ms   89.98%
    Req/Sec    79.98k    18.07k  154.64k    78.65%
  38208400 requests in 1.00m, 5.23GB read
Requests/sec: 635876.41
Transfer/sec:     89.14MB

1 แƒฌแƒฃแƒ—แƒจแƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ ~3.28-แƒฏแƒ”แƒ  แƒ’แƒแƒ˜แƒ–แƒแƒ แƒ“แƒ! แƒ›แƒแƒ’แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ›แƒฎแƒแƒšแƒแƒ“ XNUMX แƒ›แƒ˜แƒšแƒ˜แƒแƒœแƒ˜ แƒ’แƒ•แƒแƒ™แƒšแƒ“แƒ แƒ›แƒ แƒ’แƒ•แƒแƒšแƒ˜ แƒ แƒ˜แƒชแƒฎแƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ•แƒชแƒแƒ“แƒแƒ— แƒแƒ›แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒฌแƒแƒ แƒ”แƒ‘แƒ.

แƒฏแƒ”แƒ  แƒจแƒ”แƒ•แƒฎแƒ”แƒ“แƒแƒ— แƒ’แƒแƒ›แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒš แƒกแƒขแƒแƒขแƒ˜แƒกแƒขแƒ˜แƒ™แƒแƒก perf:

$ sudo perf stat -B -e task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses,cache-misses ./http_server_multithreaded

 Performance counter stats for './http_server_multithreaded':

     242446,314933      task-clock (msec)         #    4,000 CPUs utilized          
         1โ€ฏ813โ€ฏ074      context-switches          #    0,007 M/sec                  
             4โ€ฏ689      cpu-migrations            #    0,019 K/sec                  
               254      page-faults               #    0,001 K/sec                  
   895โ€ฏ324โ€ฏ830โ€ฏ170      cycles                    #    3,693 GHz                    
   621โ€ฏ378โ€ฏ066โ€ฏ808      instructions              #    0,69  insn per cycle         
   119โ€ฏ926โ€ฏ709โ€ฏ370      branches                  #  494,653 M/sec                  
     3โ€ฏ227โ€ฏ095โ€ฏ669      branch-misses             #    2,69% of all branches        
           808โ€ฏ664      cache-misses                                                

      60,604330670 seconds time elapsed

CPU Affinity-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ, แƒ™แƒแƒ›แƒžแƒ˜แƒšแƒแƒชแƒ˜แƒแƒกแƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ -march=native, PGO, แƒฐแƒ˜แƒขแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒก แƒ–แƒ แƒ“แƒ แƒฅแƒ”แƒจแƒ˜, แƒ›แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ MAX_EVENTS แƒ“แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ” EPOLLET แƒแƒ  แƒ›แƒ˜แƒกแƒชแƒ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜ แƒ–แƒ แƒ“แƒ. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ แƒ แƒ›แƒแƒฎแƒ“แƒ”แƒ‘แƒ, แƒ—แƒฃ แƒ’แƒแƒ–แƒ แƒ“แƒ˜แƒ— แƒ”แƒ แƒ—แƒ“แƒ แƒแƒฃแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒแƒก?

แƒกแƒขแƒแƒขแƒ˜แƒกแƒขแƒ˜แƒ™แƒ 352 แƒ”แƒ แƒ—แƒ“แƒ แƒแƒฃแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก:

$ wrk -c352 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 352 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.12ms    3.79ms  68.23ms   87.49%
    Req/Sec    83.78k    12.69k  169.81k    83.59%
  40006142 requests in 1.00m, 5.48GB read
Requests/sec: 665789.26
Transfer/sec:     93.34MB

แƒ›แƒ˜แƒ˜แƒฆแƒ”แƒก แƒกแƒแƒกแƒฃแƒ แƒ•แƒ”แƒšแƒ˜ แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜ แƒ“แƒ แƒ›แƒแƒกแƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒ’แƒ แƒแƒคแƒ˜แƒ™แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก 1 แƒฌแƒฃแƒ—แƒจแƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒแƒ™แƒ˜แƒ“แƒ”แƒ‘แƒฃแƒšแƒ”แƒ‘แƒแƒก แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒแƒ–แƒ”:

แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœแƒ˜ แƒจแƒ˜แƒจแƒ•แƒ”แƒšแƒ˜-C I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜

แƒฉแƒ•แƒ”แƒœ แƒ•แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒ แƒแƒ› แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒแƒกแƒ”แƒฃแƒšแƒ˜ แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒแƒ แƒ˜แƒ•แƒ” แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ แƒ›แƒ™แƒ•แƒ”แƒ—แƒ แƒแƒ“ แƒ˜แƒ™แƒšแƒ”แƒ‘แƒก (แƒ›แƒ แƒแƒ•แƒแƒšแƒœแƒแƒ™แƒแƒ“แƒฃแƒ  แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜ แƒ”แƒก แƒฃแƒคแƒ แƒ แƒจแƒ”แƒกแƒแƒ›แƒฉแƒœแƒ”แƒ•แƒ˜แƒ). แƒ”แƒก แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ Linux TCP/IP แƒกแƒขแƒ”แƒ™แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒกแƒ—แƒแƒœ? แƒ›แƒแƒ’แƒ”แƒ แƒ˜แƒ“แƒ”แƒ‘แƒแƒ— แƒ“แƒแƒฌแƒ”แƒ แƒแƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒ•แƒแƒ แƒแƒฃแƒ“แƒ”แƒ‘แƒ˜ แƒ’แƒ แƒแƒคแƒ˜แƒก แƒแƒ› แƒฅแƒชแƒ”แƒ•แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ“แƒ แƒแƒžแƒขแƒ˜แƒ›แƒ˜แƒ–แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ”แƒ‘แƒจแƒ˜.

แƒ แƒแƒ’แƒแƒ แƒช แƒแƒฆแƒœแƒ˜แƒจแƒœแƒ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ”แƒ‘แƒจแƒ˜, แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ”แƒก แƒขแƒ”แƒกแƒขแƒ˜ แƒแƒ  แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒฅแƒชแƒ”แƒ•แƒแƒก แƒ แƒ”แƒแƒšแƒฃแƒ แƒ˜ แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒฅแƒ•แƒ”แƒจ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒกแƒ—แƒแƒœ, แƒ’แƒแƒ›แƒแƒกแƒชแƒ”แƒ›แƒก แƒŸแƒฃแƒ แƒœแƒแƒšแƒ”แƒ‘แƒก, แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก แƒ™แƒ แƒ˜แƒžแƒขแƒแƒ’แƒ แƒแƒคแƒ˜แƒแƒก. TLS แƒ“แƒ แƒ.แƒจ., แƒ แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒแƒ“แƒแƒช แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ แƒฎแƒ“แƒ”แƒ‘แƒ แƒแƒ แƒแƒ”แƒ แƒ—แƒ’แƒ•แƒแƒ แƒแƒ•แƒแƒœแƒ˜ (แƒ“แƒ˜แƒœแƒแƒ›แƒ˜แƒฃแƒ แƒ˜). แƒขแƒ”แƒกแƒขแƒ”แƒ‘แƒ˜ แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ›แƒฎแƒแƒ แƒ˜แƒก แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ แƒฉแƒแƒขแƒแƒ แƒ“แƒ”แƒ‘แƒ แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ I/O แƒžแƒ แƒแƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘.

I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒœแƒแƒ™แƒšแƒแƒ•แƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜

แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ’แƒ”แƒกแƒ›แƒแƒ“แƒ”แƒ—, แƒ แƒแƒ› I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜ แƒแƒ  แƒแƒ แƒ˜แƒก แƒœแƒแƒ™แƒšแƒแƒ•แƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒ™แƒ”แƒ แƒซแƒแƒ“:

  • I/O แƒ แƒ”แƒแƒฅแƒขแƒแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ›แƒ แƒแƒ•แƒแƒšแƒซแƒแƒคแƒ˜แƒแƒœ แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒฌแƒ˜แƒšแƒแƒ“ แƒฃแƒคแƒ แƒ แƒ แƒ—แƒฃแƒšแƒ˜แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ›แƒแƒ’แƒ˜แƒฌแƒ”แƒ•แƒ— แƒœแƒแƒ™แƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒฎแƒ”แƒšแƒ˜แƒ— แƒ›แƒแƒ แƒ—แƒ•แƒ.
  • แƒžแƒ แƒแƒฅแƒขแƒ˜แƒ™แƒ แƒ’แƒ•แƒ˜แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก, แƒ แƒแƒ› แƒฃแƒ›แƒ”แƒขแƒ”แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ แƒแƒ แƒแƒ”แƒ แƒ—แƒ’แƒ•แƒแƒ แƒแƒ•แƒแƒœแƒ˜แƒ, แƒ แƒแƒ›แƒแƒช แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ˜แƒฌแƒ•แƒ˜แƒแƒก แƒ”แƒ แƒ—แƒ˜ แƒซแƒแƒคแƒ˜แƒก แƒญแƒ แƒ, แƒฎแƒแƒšแƒ แƒ›แƒ”แƒแƒ แƒ” แƒ“แƒแƒ™แƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒ—แƒ˜.
  • แƒ—แƒฃ แƒ”แƒ แƒ—แƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ“แƒแƒ‘แƒšแƒแƒ™แƒแƒ•แƒก แƒ—แƒ”แƒ›แƒแƒก, แƒ—แƒแƒ•แƒแƒ“ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒแƒ›แƒแƒ›แƒ แƒฉแƒ”แƒ•แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒ‘แƒšแƒแƒ™แƒแƒ•แƒก, แƒ แƒแƒ›แƒแƒช แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ˜แƒฌแƒ•แƒ˜แƒแƒก แƒซแƒœแƒ”แƒšแƒแƒ“ แƒกแƒแƒžแƒแƒ•แƒœแƒ”แƒšแƒ˜ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ”แƒ‘แƒ˜.

แƒฌแƒงแƒ•แƒ”แƒขแƒก แƒแƒ› แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ”แƒ‘แƒก I/O แƒžแƒ แƒแƒแƒฅแƒขแƒแƒ แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒฎแƒจแƒ˜แƒ แƒแƒ“ แƒแƒฅแƒ•แƒก แƒ’แƒ แƒแƒคแƒ˜แƒ™แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ—แƒแƒœแƒแƒ‘แƒ แƒแƒ“ แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒ‘แƒก แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒแƒก แƒซแƒแƒคแƒ”แƒ‘แƒ˜แƒก แƒแƒฃแƒ–แƒ–แƒ” แƒ“แƒ แƒแƒกแƒ”แƒ•แƒ” แƒแƒฅแƒ•แƒก แƒฃแƒคแƒ แƒ แƒ›แƒแƒกแƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒšแƒ˜ API. แƒแƒ›แƒแƒ–แƒ” แƒ›แƒแƒ’แƒ•แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ”แƒ›แƒก แƒกแƒฎแƒ•แƒ แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒ•แƒ˜แƒกแƒแƒฃแƒ‘แƒ แƒ”แƒ‘แƒ—.

แƒ“แƒแƒกแƒ™แƒ•แƒœแƒ

แƒกแƒฌแƒแƒ แƒ”แƒ“ แƒแƒฅ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ“แƒ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ›แƒแƒ’แƒ–แƒแƒฃแƒ แƒแƒ‘แƒ แƒ—แƒ”แƒแƒ แƒ˜แƒ˜แƒ“แƒแƒœ แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  แƒžแƒ แƒแƒคแƒ˜แƒšแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒœแƒแƒ‘แƒแƒšแƒฅแƒ•แƒจแƒ˜.

แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒ  แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒฉแƒ”แƒ แƒ“แƒ”แƒ— แƒแƒ›แƒแƒ–แƒ”, แƒ แƒแƒ“แƒ’แƒแƒœ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒกแƒฎแƒ•แƒ, แƒ—แƒแƒœแƒแƒ‘แƒ แƒแƒ“ แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ แƒฅแƒกแƒ”แƒšแƒฃแƒ แƒ˜ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒฃแƒšแƒ˜ แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒ˜แƒก แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ“แƒแƒœแƒ˜แƒก แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒฃแƒšแƒแƒ‘แƒ˜แƒ—แƒ แƒ“แƒ แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒ—. แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒแƒ, แƒฉแƒ”แƒ›แƒ˜ แƒแƒ–แƒ แƒ˜แƒ—, แƒฅแƒ•แƒ”แƒ›แƒแƒ— แƒ›แƒแƒชแƒ”แƒ›แƒฃแƒšแƒ˜แƒ แƒ‘แƒ›แƒฃแƒšแƒ”แƒ‘แƒ˜.

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒฏแƒ”แƒ แƒ–แƒ”!

แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜

แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ แƒ แƒฌแƒแƒ•แƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ?

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ