āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž

I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ (āĻāĻ•āĻ• āĻĨā§āĻ°ā§‡āĻĄ āĻ˜āĻŸāĻ¨āĻž āĻ˛ā§āĻĒ) āĻ‰āĻšā§āĻš-āĻ˛ā§‹āĻĄ āĻ¸āĻĢā§āĻŸāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ˛ā§‡āĻ–āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨, āĻ¯āĻž āĻ…āĻ¨ā§‡āĻ• āĻœāĻ¨āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§‡ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻšāĻ¯āĻŧ:

āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡, āĻ†āĻŽāĻ°āĻž āĻāĻ•āĻŸāĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻ° āĻ‡āĻ¨āĻ¸ āĻāĻŦāĻ‚ āĻ†āĻ‰āĻŸāĻ—ā§āĻ˛āĻŋ āĻĻā§‡āĻ–āĻŦ āĻāĻŦāĻ‚ āĻāĻŸāĻŋ āĻ•ā§€āĻ­āĻžāĻŦā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡, 200 āĻ˛āĻžāĻ‡āĻ¨ā§‡āĻ° āĻ•āĻŽ āĻ•ā§‹āĻĄā§‡ āĻāĻ•āĻŸāĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ˛āĻŋāĻ–āĻŦ āĻāĻŦāĻ‚ 40 āĻŽāĻŋāĻ˛āĻŋāĻ¯āĻŧāĻ¨ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§/āĻŽāĻŋāĻ¨āĻŋāĻŸā§‡āĻ° āĻŦā§‡āĻļāĻŋ āĻāĻ•āĻŸāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ HTTP āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻŦā§ˇ

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž

  • āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻ° āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻžāĻ°āĻŋāĻ¤āĻž āĻŦā§‹āĻāĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ‡ āĻāĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻā§āĻāĻ•āĻŋāĻ—ā§āĻ˛āĻŋ āĻŦā§‹āĻāĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‡āĻ–āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĨ¤
  • āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋ āĻŦā§āĻāĻ¤ā§‡ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻœā§āĻžāĻžāĻ¨ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨āĨ¤ āĻ¸āĻŋ āĻ­āĻžāĻˇāĻž āĻāĻŦāĻ‚ āĻ¨ā§‡āĻŸāĻ“āĻ¯āĻŧāĻžāĻ°ā§āĻ• āĻ…ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻ•ā§‡āĻļāĻ¨ āĻŦāĻŋāĻ•āĻžāĻļā§‡ āĻ•āĻŋāĻ›ā§ āĻ…āĻ­āĻŋāĻœā§āĻžāĻ¤āĻžāĨ¤
  • āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•ā§‹āĻĄ āĻ•āĻ ā§‹āĻ°āĻ­āĻžāĻŦā§‡ āĻ¸āĻŋ āĻ­āĻžāĻˇāĻžāĻ¯āĻŧ āĻ˛ā§‡āĻ–āĻž āĻšāĻ¯āĻŧ (āĻ¸āĻ¤āĻ°ā§āĻ•āĻ¤āĻž: āĻĻā§€āĻ°ā§āĻ˜ āĻĒāĻŋāĻĄāĻŋāĻāĻĢ) C11 āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄā§‡ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻŦāĻ‚ āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ GitHub.

āĻ•ā§‡āĻ¨ āĻāĻ‡ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ?

āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻ¨ā§‡āĻŸā§‡āĻ° āĻ•ā§āĻ°āĻŽāĻŦāĻ°ā§āĻ§āĻŽāĻžāĻ¨ āĻœāĻ¨āĻĒā§āĻ°āĻŋāĻ¯āĻŧāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§‡, āĻ“āĻ¯āĻŧā§‡āĻŦ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°āĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻāĻ•āĻ‡ āĻ¸āĻžāĻĨā§‡ āĻĒā§āĻ°āĻšā§āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻ• āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻž āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ āĻšāĻ¤ā§‡ āĻļā§āĻ°ā§ āĻ•āĻ°ā§‡, āĻāĻŦāĻ‚ āĻ¤āĻžāĻ‡ āĻĻā§āĻŸāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛: āĻĒā§āĻ°āĻšā§āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻ• OS āĻĨā§āĻ°ā§‡āĻĄā§‡ I/O āĻŦā§āĻ˛āĻ• āĻ•āĻ°āĻž āĻāĻŦāĻ‚ I/O-āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ•āĻ¤ā§āĻ°ā§‡ āĻŦā§āĻ˛āĻ• āĻ•āĻ°āĻž āĻ¨āĻ¯āĻŧ āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻŦāĻŋāĻœā§āĻžāĻĒā§āĻ¤āĻŋ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ, āĻ¯āĻžāĻ•ā§‡ "āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ•"āĻ“ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ (āĻ‡āĻĒā§‹āĻ˛/kqueue/āĻ†āĻ‡āĻ“āĻ¸āĻŋāĻĒāĻŋ/āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ)āĨ¤

āĻĒā§āĻ°āĻĨāĻŽ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§‡ āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ†āĻ—āĻ¤ āĻ¸āĻ‚āĻ¯ā§‹āĻ—ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ OS āĻĨā§āĻ°ā§‡āĻĄ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž āĻœāĻĄāĻŧāĻŋāĻ¤āĨ¤ āĻāĻ° āĻ…āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻšāĻ˛ āĻĻā§āĻ°ā§āĻŦāĻ˛ āĻŽāĻžāĻĒāĻ¯ā§‹āĻ—ā§āĻ¯āĻ¤āĻž: āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽāĻ•ā§‡ āĻ…āĻ¨ā§‡āĻ•āĻ—ā§āĻ˛āĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻĒā§āĻ°āĻ¸āĻ™ā§āĻ— āĻ°ā§‚āĻĒāĻžāĻ¨ā§āĻ¤āĻ° и āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ•āĻ˛. āĻāĻ—ā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻ¯āĻŧāĻŦāĻšā§āĻ˛ āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ˛āĻžāĻĒ āĻāĻŦāĻ‚ āĻāĻ•āĻŸāĻŋ āĻšāĻŋāĻ¤ā§āĻ¤āĻžāĻ•āĻ°ā§āĻˇāĻ• āĻ¸āĻ‚āĻ–ā§āĻ¯āĻ• āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻ¸āĻš āĻŦāĻŋāĻ¨āĻžāĻŽā§‚āĻ˛ā§āĻ¯ā§‡ RAM āĻāĻ° āĻ…āĻ­āĻžāĻŦ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ā§ˇ

āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻšāĻžāĻ‡āĻ˛āĻžāĻ‡āĻŸ āĻĨā§āĻ°ā§‡āĻĄā§‡āĻ° āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž (āĻĨā§āĻ°ā§‡āĻĄ āĻĒā§āĻ˛), āĻ¯āĻžāĻ° āĻĢāĻ˛ā§‡ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽāĻŸāĻŋāĻ•ā§‡ āĻāĻ•ā§āĻ¸āĻŋāĻ•āĻŋāĻ‰āĻļāĻ¨ āĻŦāĻžāĻ¤āĻŋāĻ˛ āĻ•āĻ°āĻž āĻĨā§‡āĻ•ā§‡ āĻŦāĻžāĻ§āĻž āĻĻā§‡āĻ¯āĻŧ, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ•āĻ‡ āĻ¸āĻžāĻĨā§‡ āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻĒā§āĻ°āĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°ā§‡: āĻ¯āĻĻāĻŋ āĻāĻ•āĻŸāĻŋ āĻĨā§āĻ°ā§‡āĻĄ āĻĒā§āĻ˛ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ā§‡ āĻĻā§€āĻ°ā§āĻ˜ āĻĒāĻ āĻŋāĻ¤ āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ˛āĻžāĻĒ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ…āĻŦāĻ°ā§āĻĻā§āĻ§ āĻĨāĻžāĻ•ā§‡, āĻ¤āĻŦā§‡ āĻ…āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ¸āĻ•ā§‡āĻŸāĻ—ā§āĻ˛āĻŋ āĻ¯āĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻĄā§‡āĻŸāĻž āĻ—ā§āĻ°āĻšāĻŖ āĻ•āĻ°āĻ¤ā§‡ āĻ¸āĻ•ā§āĻˇāĻŽ āĻšāĻŦā§‡ āĻ¤āĻž āĻ¸āĻ•ā§āĻˇāĻŽ āĻšāĻŦā§‡ āĻ¨āĻž āĻ¤āĻžāĻ‡ āĻ•āĻ°ā§‡āĻž.

āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻŦāĻŋāĻœā§āĻžāĻĒā§āĻ¤āĻŋ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ (āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ•) OS āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻĻāĻ¤ā§āĻ¤āĨ¤ āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋ I/O āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ˛āĻžāĻĒā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ¸āĻ¤āĻ°ā§āĻ•āĻ¤āĻžāĻ° (āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ, āĻŦāĻŋāĻœā§āĻžāĻĒā§āĻ¤āĻŋ) āĻ‰āĻĒāĻ° āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°ā§‡, āĻ¸āĻŦāĻšā§‡āĻ¯āĻŧā§‡ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ§āĻ°āĻŖā§‡āĻ° āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ• āĻ¨āĻŋāĻ¯āĻŧā§‡ āĻ†āĻ˛ā§‹āĻšāĻ¨āĻž āĻ•āĻ°ā§‡āĨ¤ āĻ¤āĻžāĻĻā§‡āĻ° āĻ¸āĻŽāĻžāĻĒā§āĻ¤āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻŦāĻŋāĻœā§āĻžāĻĒā§āĻ¤āĻŋ. āĻāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ¸āĻ°āĻ˛ā§€āĻ•ā§ƒāĻ¤ āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻŦā§āĻ˛āĻ• āĻĄāĻžāĻ¯āĻŧāĻžāĻ—ā§āĻ°āĻžāĻŽ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ‰āĻĒāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡:

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ

āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āĻ¯ āĻ¨āĻŋāĻŽā§āĻ¨āĻ°ā§‚āĻĒ:

  • I/O āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻŦā§āĻ˛āĻ• āĻ•āĻ°āĻž āĻ¸ā§āĻĨāĻ—āĻŋāĻ¤ āĻ•āĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻĒā§āĻ°āĻŦāĻžāĻš āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤OS āĻ¸āĻ āĻŋāĻ•āĻ­āĻžāĻŦā§‡ āĻ¨āĻž āĻšāĻ“āĻ¯āĻŧāĻž āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻĄāĻŋāĻĢā§āĻ°ā§āĻ¯āĻžāĻ—āĻŽā§‡āĻ¨ā§āĻŸāĻ¸ āĻ‡āĻ¨āĻ•āĻžāĻŽāĻŋāĻ‚ āĻ†āĻ‡āĻĒāĻŋ āĻĒā§āĻ¯āĻžāĻ•ā§‡āĻŸ āĻŦāĻžāĻ‡āĻŸ āĻ¸ā§āĻŸā§āĻ°āĻŋāĻŽ āĻ•āĻ°āĻ¤ā§‡ (āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ TCP, āĻĄā§‡āĻŸāĻž āĻ—ā§āĻ°āĻšāĻŖ āĻ•āĻ°āĻž) āĻ…āĻĨāĻŦāĻž āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€āĻ¤ā§‡ āĻĒāĻžāĻ āĻžāĻ¨ā§‹āĻ° āĻœāĻ¨ā§āĻ¯ āĻ…āĻ­ā§āĻ¯āĻ¨ā§āĻ¤āĻ°ā§€āĻŖ āĻ˛ā§‡āĻ–āĻžāĻ° āĻŦāĻžāĻĢāĻžāĻ°āĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻĒāĻ°ā§āĻ¯āĻžāĻĒā§āĻ¤ āĻœāĻžāĻ¯āĻŧāĻ—āĻž āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ¯āĻžāĻŦā§‡ āĻ¨āĻž āĻ•āĻŋāĻ›ā§āĻ‡ (āĻĄā§‡āĻŸāĻž āĻĒāĻžāĻ āĻžāĻ¨ā§‹)āĨ¤
  • āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ• āĻ¸āĻŽāĻ¯āĻŧā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ¸āĻžāĻĨā§‡ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻ•ā§‡ āĻ…āĻŦāĻšāĻŋāĻ¤ āĻ•āĻ°ā§‡ āĻ¯ā§‡ OS āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻĄāĻŋāĻĢā§āĻ°ā§āĻ¯āĻžāĻ—āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻĄ āĻ†āĻ‡āĻĒāĻŋ āĻĒā§āĻ¯āĻžāĻ•ā§‡āĻŸ (āĻŸāĻŋāĻ¸āĻŋāĻĒāĻŋ, āĻĄā§‡āĻŸāĻž āĻ°āĻŋāĻ¸ā§‡āĻĒāĻļāĻ¨) āĻŦāĻž āĻ…āĻ­ā§āĻ¯āĻ¨ā§āĻ¤āĻ°ā§€āĻŖ āĻ˛ā§‡āĻ–āĻžāĻ° āĻŦāĻžāĻĢāĻžāĻ°āĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻ¯āĻĨā§‡āĻˇā§āĻŸ āĻœāĻžāĻ¯āĻŧāĻ—āĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ (āĻĄā§‡āĻŸāĻž āĻĒāĻžāĻ āĻžāĻ¨ā§‹)āĨ¤

āĻ¸āĻ‚āĻ•ā§āĻˇā§‡āĻĒā§‡ āĻŦāĻ˛āĻ¤ā§‡ āĻ—ā§‡āĻ˛ā§‡, āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ I/O-āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ OS āĻĨā§āĻ°ā§‡āĻĄ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻž āĻ•āĻŽā§āĻĒāĻŋāĻ‰āĻŸāĻŋāĻ‚ āĻļāĻ•ā§āĻ¤āĻŋāĻ° āĻ…āĻĒāĻšāĻ¯āĻŧ, āĻ•āĻžāĻ°āĻŖ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦā§‡, āĻĨā§āĻ°ā§‡āĻĄāĻ—ā§āĻ˛āĻŋ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ•āĻžāĻœ āĻ•āĻ°āĻ›ā§‡ āĻ¨āĻž (āĻ…āĻ¤āĻāĻŦ āĻļāĻŦā§āĻĻāĻŸāĻŋ "āĻ¸āĻĢā§āĻŸāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻŦāĻžāĻ§āĻž") āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ• āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻŸāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°ā§‡, āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻŸāĻŋāĻ•ā§‡ āĻ¸āĻŋāĻĒāĻŋāĻ‡āĻ‰ āĻ¸āĻ‚āĻ¸ā§āĻĨāĻžāĻ¨āĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ…āĻ°ā§āĻĨāĻ¨ā§ˆāĻ¤āĻŋāĻ•āĻ­āĻžāĻŦā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻžāĻ° āĻ…āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§‡āĻ¯āĻŧāĨ¤

I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ āĻŽāĻĄā§‡āĻ˛

I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ• āĻāĻŦāĻ‚ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻ•ā§‹āĻĄā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸ā§āĻ¤āĻ° āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡āĨ¤ āĻāĻ° āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ā§‡āĻ° āĻ¨ā§€āĻ¤āĻŋāĻŸāĻŋ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻŦā§āĻ˛āĻ• āĻĄāĻžāĻ¯āĻŧāĻžāĻ—ā§āĻ°āĻžāĻŽ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡:

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ

  • āĻ†āĻŽāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŽāĻ¨ā§‡ āĻ•āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĻāĻŋāĻ‡ āĻ¯ā§‡ āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻšāĻ˛ āĻāĻ•āĻŸāĻŋ āĻŦāĻŋāĻœā§āĻžāĻĒā§āĻ¤āĻŋ āĻ¯ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ¸āĻ•ā§‡āĻŸ āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¨-āĻŦā§āĻ˛āĻ•āĻŋāĻ‚ I/O āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻ¸āĻ•ā§āĻˇāĻŽāĨ¤
  • āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻžāĻ° āĻšāĻ˛ āĻāĻ•āĻŸāĻŋ āĻĢāĻžāĻ‚āĻļāĻ¨ āĻ¯āĻžāĻ•ā§‡ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĄāĻžāĻ•āĻž āĻšāĻ¯āĻŧ āĻ¯āĻ–āĻ¨ āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻšāĻ¯āĻŧ, āĻ¯āĻž āĻĒāĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…-āĻŦā§āĻ˛āĻ•āĻŋāĻ‚ I/O āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻ•āĻ°ā§‡āĨ¤

āĻāĻŸāĻŋ āĻ˛āĻ•ā§āĻˇ āĻ•āĻ°āĻž āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻ¯ā§‡ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻŸāĻŋ āĻ¸āĻ‚āĻœā§āĻžāĻž āĻ…āĻ¨ā§āĻ¸āĻžāĻ°ā§‡ āĻāĻ•āĻ•-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ, āĻ¤āĻŦā§‡ āĻ§āĻžāĻ°āĻŖāĻžāĻŸāĻŋāĻ•ā§‡ 1 āĻĨā§āĻ°ā§‡āĻĄ: 1 āĻ°āĻŋāĻ…ā§āĻ¯āĻžāĻ•ā§āĻŸāĻ°ā§‡āĻ° āĻ…āĻ¨ā§āĻĒāĻžāĻ¤ā§‡ āĻŦāĻšā§-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻĒāĻ°āĻŋāĻŦā§‡āĻļā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻĨā§‡āĻ•ā§‡ āĻŦāĻŋāĻ°āĻ¤ āĻ•āĻ°āĻžāĻ° āĻ•āĻŋāĻ›ā§ āĻ¨ā§‡āĻ‡, āĻ¯āĻžāĻ° āĻĢāĻ˛ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ CPU āĻ•ā§‹āĻ° āĻĒā§āĻ¨āĻ°ā§āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĨ¤

āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨

āĻ†āĻŽāĻ°āĻž āĻāĻ•āĻŸāĻŋ āĻĢāĻžāĻ‡āĻ˛ā§‡ āĻĒāĻžāĻŦāĻ˛āĻŋāĻ• āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻĢā§‡āĻ¸ āĻ°āĻžāĻ–āĻŦ reactor.h, āĻāĻŦāĻ‚ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ - āĻŽāĻ§ā§āĻ¯ā§‡ reactor.c. reactor.h āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻ˜ā§‹āĻˇāĻŖāĻžāĻ—ā§āĻ˛āĻŋ āĻ¨āĻŋāĻ¯āĻŧā§‡ āĻ—āĻ āĻŋāĻ¤ āĻšāĻŦā§‡:

reactor.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 (āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻžāĻ°ā§‡āĻ° āĻ•āĻžāĻ āĻžāĻŽā§‹ āĻāĻŦāĻ‚ āĻāĻŸāĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻ¯ā§āĻ•ā§āĻ¤āĻŋ)āĨ¤

āĻ°āĻŋāĻ…ā§āĻ¯āĻžāĻ•ā§āĻŸāĻ° āĻāĻŦāĻ‚ āĻ•āĻ˛āĻŦā§āĻ¯āĻžāĻ•āĻĄā§‡āĻŸāĻž āĻĻā§‡āĻ–āĻžāĻ¨

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

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

āĻĻāĻ¯āĻŧāĻž āĻ•āĻ°ā§‡ āĻŽāĻ¨ā§‡ āĻ°āĻžāĻ–āĻŦā§‡āĻ¨ āĻ¯ā§‡ āĻ†āĻŽāĻ°āĻž āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻž āĻ•āĻ°āĻžāĻ° āĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ¸āĻ•ā§āĻˇāĻŽ āĻ•āĻ°ā§‡āĻ›āĻŋ āĻ…āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻĒā§āĻ°āĻ•āĻžāĻ° āĻ¸ā§‚āĻšāĻ• āĻ…āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧā§€āĨ¤ āĻ­āĻŋāĻ¤āĻ°ā§‡ 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;
}

āĻ¸āĻ‚āĻ•ā§āĻˇā§‡āĻĒā§‡, āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻ•ā§‹āĻĄā§‡ āĻĢāĻžāĻ‚āĻļāĻ¨ āĻ•āĻ˛ā§‡āĻ° āĻšā§‡āĻ‡āĻ¨ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻĢāĻ°ā§āĻŽāĻŸāĻŋ āĻ—ā§āĻ°āĻšāĻŖ āĻ•āĻ°āĻŦā§‡:

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ 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 (āĻ°āĻŋāĻŸāĻžāĻ°ā§āĻ¨ āĻĄā§‡āĻŸāĻž āĻŸāĻžāĻ‡āĻĒ)āĨ¤
  • <ДАННĐĢЕ> - āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻ•āĻ°āĻž āĻĄā§‡āĻŸāĻžāĨ¤ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻāĻŸāĻŋ āĻ‡āĻŽā§‡āĻœā§‡āĻ° āĻĒāĻĨ āĻāĻ‡āĻšāĻŸāĻŋāĻāĻŽāĻāĻ˛.

āĻĢāĻžāĻ‡āĻ˛ http_server.c (āĻāĻ•āĻ• āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°) āĻĢāĻžāĻ‡āĻ˛ āĻ…āĻ¨ā§āĻ¤āĻ°ā§āĻ­ā§āĻ•ā§āĻ¤ āĻ•āĻ°ā§‡ common.h, āĻ¯āĻž āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻĢāĻžāĻ‚āĻļāĻ¨ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻŸāĻžāĻ‡āĻĒ āĻ§āĻžāĻ°āĻŖ āĻ•āĻ°ā§‡:

āĻĢāĻžāĻ‚āĻļāĻ¨ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻŸāĻžāĻ‡āĻĒ āĻĻā§‡āĻ–āĻžāĻ¨ common.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(). āĻŽā§āĻ¯āĻžāĻ•ā§āĻ°ā§‹ āĻāĻ•ā§āĻ¸āĻĒā§āĻ°ā§‡āĻļāĻ¨ā§‡āĻ° āĻŽāĻžāĻ¨āĻ•ā§‡ āĻ¤ā§āĻ°ā§āĻŸāĻŋāĻ° āĻ¸āĻžāĻĨā§‡ āĻ¤ā§āĻ˛āĻ¨āĻž āĻ•āĻ°ā§‡ āĻāĻŦāĻ‚ āĻļāĻ°ā§āĻ¤āĻŸāĻŋ āĻ¸āĻ¤ā§āĻ¯ āĻšāĻ˛ā§‡ āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋāĻ•ā§‡ āĻ•āĻ˛ āĻ•āĻ°ā§‡ 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().

āĻ…āĻ¨_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(), āĻĄā§‡āĻŸāĻž āĻĒāĻžāĻ āĻžāĻ¨ā§‹āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĨ¤ āĻāĻ‡ āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋ āĻ•ā§āĻ˛āĻžāĻ¯āĻŧā§‡āĻ¨ā§āĻŸāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻšāĻŋāĻ¤ā§āĻ° āĻ¸āĻš HTML āĻ¸āĻš āĻāĻ•āĻŸāĻŋ HTTP āĻĒā§āĻ°āĻ¤āĻŋāĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒāĻžāĻ āĻžāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻžāĻ°āĻ•ā§‡ āĻ†āĻŦāĻžāĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°ā§‡ 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 āĻĒā§āĻ°āĻœā§‡āĻ•ā§āĻŸ āĻ°ā§āĻŸā§‡) āĻāĻŦāĻ‚ āĻ¸ā§āĻŦ-āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻšāĻžāĻ˛ā§ āĻ•āĻ°ā§āĻ¨, āĻ–ā§āĻ˛ā§āĻ¨ http://127.0.0.1:18470 āĻŦā§āĻ°āĻžāĻ‰āĻœāĻžāĻ°ā§‡ āĻāĻŦāĻ‚ āĻĻā§‡āĻ–ā§āĻ¨ āĻ†āĻŽāĻ°āĻž āĻ•āĻŋ āĻ†āĻļāĻž āĻ•āĻ°ā§‡āĻ›āĻŋ:

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ 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 āĻŽāĻŋāĻ˛āĻŋāĻ¯āĻŧāĻ¨ āĻ•āĻŽ āĻ›āĻŋāĻ˛āĻžāĻŽ, āĻ¤āĻžāĻ‡ āĻ†āĻ¸ā§āĻ¨ āĻāĻŸāĻŋ āĻ āĻŋāĻ• āĻ•āĻ°āĻžāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°āĻŋāĨ¤

āĻĒā§āĻ°āĻĨāĻŽā§‡ āĻ‰āĻ¤ā§āĻĒāĻ¨ā§āĻ¨ āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨ āĻĻā§‡āĻ–āĻŋ āĻĒāĻžāĻ°āĻĢ:

$ 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

āĻ¸āĻŋāĻĒāĻŋāĻ‡āĻ‰ āĻ…ā§āĻ¯āĻžāĻĢāĻŋāĻ¨āĻŋāĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž, āĻ¸āĻ™ā§āĻ—ā§‡ āĻ¸āĻ‚āĻ•āĻ˛āĻ¨ -march=native, āĻĒāĻŋāĻœāĻŋāĻ“, āĻšāĻŋāĻŸ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻŦā§ƒāĻĻā§āĻ§āĻŋ āĻ¨āĻ—āĻĻ, āĻŦā§ƒāĻĻā§āĻ§āĻŋ 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 āĻŽāĻŋāĻ¨āĻŋāĻŸā§‡ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•ā§ƒāĻ¤ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻ­āĻ°āĻ¤āĻž āĻĻā§‡āĻ–āĻžāĻ¯āĻŧ:

āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯āĻ¯ā§āĻ•ā§āĻ¤ āĻŦā§‡āĻ¯āĻŧāĻžāĻ°-āĻ¸āĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ

āĻ†āĻŽāĻ°āĻž āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻšā§āĻ›āĻŋ āĻ¯ā§‡ āĻ•āĻ¯āĻŧā§‡āĻ•āĻļā§‹ āĻ¸āĻ‚āĻ¯ā§‹āĻ—ā§‡āĻ° āĻĒāĻ°ā§‡, āĻ‰āĻ­āĻ¯āĻŧ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•ā§ƒāĻ¤ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻĻā§āĻ°ā§āĻ¤ āĻšā§āĻ°āĻžāĻ¸ āĻĒāĻžāĻ¯āĻŧ (āĻŽāĻžāĻ˛ā§āĻŸāĻŋ-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻāĻŸāĻŋ āĻ†āĻ°āĻ“ āĻ˛āĻ•ā§āĻˇāĻŖā§€āĻ¯āĻŧ)āĨ¤ āĻāĻŸāĻŋ āĻ•āĻŋ āĻ˛āĻŋāĻ¨āĻžāĻ•ā§āĻ¸ āĻŸāĻŋāĻ¸āĻŋāĻĒāĻŋ/āĻ†āĻ‡āĻĒāĻŋ āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ• āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāĻ¤? āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ā§‡ āĻŦāĻšā§-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻāĻŦāĻ‚ āĻāĻ•āĻ•-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻ—ā§āĻ°āĻžāĻĢā§‡āĻ° āĻāĻ‡ āĻ†āĻšāĻ°āĻŖ āĻāĻŦāĻ‚ āĻ…āĻĒā§āĻŸāĻŋāĻŽāĻžāĻ‡āĻœā§‡āĻļāĻ¨ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ…āĻ¨ā§āĻŽāĻžāĻ¨āĻ—ā§āĻ˛āĻŋ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻŦāĻŋāĻ§āĻžāĻ¯āĻŧ āĻ˛āĻŋāĻ–ā§āĻ¨ā§ˇ

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ‰āĻ˛ā§āĻ˛ā§‡āĻ–ā§āĻ¯ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ā§‡, āĻāĻ‡ āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻĒāĻ°ā§€āĻ•ā§āĻˇāĻž āĻŦāĻžāĻ¸ā§āĻ¤āĻŦ āĻ˛ā§‹āĻĄā§‡āĻ° āĻ…āĻ§ā§€āĻ¨ā§‡ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻ° āĻ†āĻšāĻ°āĻŖ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧ āĻ¨āĻž, āĻ•āĻžāĻ°āĻŖ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¸āĻŦāĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻ…ā§āĻ¯āĻžāĻ•ā§āĻŸ āĻ•āĻ°ā§‡, āĻ˛āĻ— āĻ†āĻ‰āĻŸāĻĒā§āĻŸ āĻ•āĻ°ā§‡, āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸā§‹āĻ—ā§āĻ°āĻžāĻĢāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ TLS āĻāĻ° āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ, āĻ¯āĻžāĻ° āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§‚āĻĒ āĻ˛ā§‹āĻĄ āĻ…-āĻ‡āĻ¨āĻŋāĻĢāĻ°ā§āĻŽ (āĻ—āĻ¤āĻŋāĻļā§€āĻ˛) āĻšāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ¯āĻŧāĨ¤ I/O āĻĒā§āĻ°ā§‹āĻ…āĻ•ā§āĻŸāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡ āĻ¤ā§ƒāĻ¤ā§€āĻ¯āĻŧ āĻĒāĻ•ā§āĻˇā§‡āĻ° āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ•āĻ¸āĻžāĻĨā§‡ āĻĒāĻ°ā§€āĻ•ā§āĻˇāĻž āĻ•āĻ°āĻž āĻšāĻŦā§‡āĨ¤

I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻ° āĻ…āĻ¸ā§āĻŦāĻŋāĻ§āĻž

āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŦā§āĻāĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¯ā§‡ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋāĻŸāĻŋ āĻ¤āĻžāĻ° āĻ¤ā§āĻ°ā§āĻŸāĻŋāĻ—ā§āĻ˛āĻŋ āĻ›āĻžāĻĄāĻŧāĻž āĻ¨āĻ¯āĻŧ, āĻ¯āĻĨāĻž:

  • āĻŽāĻžāĻ˛ā§āĻŸāĻŋ-āĻĨā§āĻ°ā§‡āĻĄā§‡āĻĄ āĻĒāĻ°āĻŋāĻŦā§‡āĻļā§‡ āĻāĻ•āĻŸāĻŋ I/O āĻšā§āĻ˛ā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻ•āĻŋāĻ›ā§āĻŸāĻž āĻŦā§‡āĻļāĻŋ āĻ•āĻ āĻŋāĻ¨, āĻ•āĻžāĻ°āĻŖ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻĒā§āĻ°āĻŦāĻžāĻš āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻž āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤
  • āĻ…āĻ¨ā§āĻļā§€āĻ˛āĻ¨ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧ āĻ¯ā§‡ āĻŦā§‡āĻļāĻŋāĻ°āĻ­āĻžāĻ— āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻ˛ā§‹āĻĄ āĻ…-āĻ‡āĻ¨āĻŋāĻĢāĻ°ā§āĻŽ, āĻ¯āĻžāĻ° āĻĢāĻ˛ā§‡ āĻāĻ•āĻŸāĻŋ āĻĨā§āĻ°ā§‡āĻĄ āĻ˛āĻ—āĻŋāĻ‚ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ¯āĻ–āĻ¨ āĻ…āĻ¨ā§āĻ¯āĻŸāĻŋ āĻ•āĻžāĻœā§‡ āĻŦā§āĻ¯āĻ¸ā§āĻ¤ āĻĨāĻžāĻ•ā§‡āĨ¤
  • āĻ¯āĻĻāĻŋ āĻāĻ•āĻŸāĻŋ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻžāĻ° āĻāĻ•āĻŸāĻŋ āĻĨā§āĻ°ā§‡āĻĄ āĻŦā§āĻ˛āĻ• āĻ•āĻ°ā§‡, āĻ¤āĻŦā§‡ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ• āĻ¨āĻŋāĻœā§‡āĻ‡ āĻŦā§āĻ˛āĻ• āĻ•āĻ°āĻŦā§‡, āĻ¯āĻž āĻ–ā§āĻāĻœā§‡ āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ•āĻ āĻŋāĻ¨ āĻŦāĻžāĻ—āĻ—ā§āĻ˛āĻŋāĻ° āĻĻāĻŋāĻ•ā§‡ āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻŋāĻ¤ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤

āĻāĻ¸āĻŦ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ•āĻ°ā§‡ āĻ†āĻ‡/āĻ“ āĻĒā§āĻ°āĻ•ā§āĻŸāĻ°, āĻ¯āĻžāĻ° āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻ‡ āĻāĻ•āĻŸāĻŋ āĻļāĻŋāĻĄāĻŋāĻ‰āĻ˛āĻžāĻ° āĻĨāĻžāĻ•ā§‡ āĻ¯āĻž āĻĨā§āĻ°ā§‡āĻĄā§‡āĻ° āĻĒā§āĻ˛ā§‡ āĻ¸āĻŽāĻžāĻ¨āĻ­āĻžāĻŦā§‡ āĻ˛ā§‹āĻĄ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ•āĻ°ā§‡ āĻāĻŦāĻ‚ āĻ†āĻ°āĻ“ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻœāĻ¨āĻ• API āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ†āĻŽāĻ°āĻž āĻāĻŸāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻĒāĻ°ā§‡ āĻ•āĻĨāĻž āĻŦāĻ˛āĻŦ, āĻ†āĻŽāĻžāĻ° āĻ…āĻ¨ā§āĻ¯ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡āĨ¤

āĻ‰āĻĒāĻ¸āĻ‚āĻšāĻžāĻ°

āĻāĻ–āĻžāĻ¨ā§‡āĻ‡ āĻ¤āĻ¤ā§āĻ¤ā§āĻŦ āĻĨā§‡āĻ•ā§‡ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻĒā§āĻ°ā§‹āĻĢāĻžāĻ‡āĻ˛āĻžāĻ° āĻāĻ•ā§āĻ¸āĻžāĻ¸ā§āĻŸā§‡ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¯āĻžāĻ¤ā§āĻ°āĻž āĻļā§‡āĻˇ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤

āĻ†āĻĒāĻ¨āĻžāĻ° āĻāĻŸāĻŋāĻ¤ā§‡ āĻĨāĻžāĻ•āĻž āĻ‰āĻšāĻŋāĻ¤ āĻ¨āĻ¯āĻŧ, āĻ•āĻžāĻ°āĻŖ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ¸ā§āĻ¤āĻ°ā§‡āĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻāĻŦāĻ‚ āĻ—āĻ¤āĻŋ āĻ¸āĻš āĻ¨ā§‡āĻŸāĻ“āĻ¯āĻŧāĻžāĻ°ā§āĻ• āĻ¸āĻĢā§āĻŸāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ˛ā§‡āĻ–āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻ°āĻ“ āĻ…āĻ¨ā§‡āĻ•āĻ—ā§āĻ˛āĻŋ āĻ¸āĻŽāĻžāĻ¨ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧ āĻĒāĻ¨ā§āĻĨāĻž āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧ, āĻ†āĻŽāĻžāĻ° āĻŽāĻ¤ā§‡, āĻ˛āĻŋāĻ™ā§āĻ• āĻ¨ā§€āĻšā§‡ āĻĻā§‡āĻ“āĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ.

ВŅŅ‚Ņ€ĐĩŅ‡ ĐŊОвŅ‹Ņ… вŅŅ‚Ņ€ĐĩŅ‡!

āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§€āĻ¯āĻŧ āĻĒā§āĻ°āĻ•āĻ˛ā§āĻĒ

āĻ†āĻ° āĻ•āĻŋ āĻĒāĻĄāĻŧāĻ¤ā§‡ āĻšāĻŦā§‡?

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨