๐Ÿฆ€ Rust์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ: Tokio ํ”„๋ ˆ์ž„์›Œํฌ ํ™œ์šฉ ๐Ÿš€

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿฆ€ Rust์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ: Tokio ํ”„๋ ˆ์ž„์›Œํฌ ํ™œ์šฉ ๐Ÿš€

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ์ •๋ง ํ•ซํ•œ ์ฃผ์ œ๋กœ ์ฐพ์•„์™”์–ด์š”. ๋ฐ”๋กœ Rust ์–ธ์–ด์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ Tokio ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. ๐Ÿ˜Ž ์ด ์ฃผ์ œ, ์–ด๋ ต๊ฒŒ ๋“ค๋ฆฌ์‹œ๋‚˜์š”? ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์ œ๊ฐ€ ์‰ฝ๊ณ  ์žฌ๋ฏธ์žˆ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”. ๋งˆ์น˜ ์นดํ†ก์œผ๋กœ ์ˆ˜๋‹ค ๋– ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ใ…‹ใ…‹ใ…‹

๊ทธ๋Ÿผ ์ด์ œ๋ถ€ํ„ฐ Rust์™€ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ธ๊ณ„๋กœ ํ•จ๊ป˜ ๋– ๋‚˜๋ณผ๊นŒ์š”? ๐Ÿš€

์ž ๊น! ํ˜น์‹œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๊ด€์‹ฌ ์žˆ์œผ์‹ ๊ฐ€์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ์žฌ๋Šฅ๋„ท(https://www.jaenung.net)์—์„œ ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€๋ จ ์žฌ๋Šฅ์„ ์ฐพ์•„๋ณด์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ์‹ค๋ ฅ ํ–ฅ์ƒ์— ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป

1. Rust, ๋„Œ ๋Œ€์ฒด ๋ญ๋‹ˆ? ๐Ÿค”

์ž, ๋จผ์ € Rust์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊นŒ์š”? Rust๋Š” ์š”์ฆ˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค ์‚ฌ์ด์—์„œ ์—„์ฒญ ํ•ซํ•œ ์–ธ์–ด์˜ˆ์š”. ๋งˆ์น˜ ์•„์ด๋Œ ๊ทธ๋ฃน BTS์ฒ˜๋Ÿผ ์ธ๊ธฐ ํญ๋ฐœ์ด์ฃ ! ใ…‹ใ…‹ใ…‹

Rust๋Š” Mozilla์—์„œ ๊ฐœ๋ฐœํ•œ ์‹œ์Šคํ…œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ, ์•ˆ์ „์„ฑ, ๋™์‹œ์„ฑ, ๊ทธ๋ฆฌ๊ณ  ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ์žก์•˜์–ด์š”. ์™€, ๋Œ€๋ฐ•์ด์ฃ ? ๐Ÿ˜ฎ

  • ์•ˆ์ „์„ฑ: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ์ปดํŒŒ์ผ ์‹œ์ ์— ์žก์•„๋‚ด์š”. ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ? ์•ˆ๋…•~ ๐Ÿ‘‹
  • ๋™์‹œ์„ฑ: ์Šค๋ ˆ๋“œ ๊ฐ„ ๋ฐ์ดํ„ฐ ๋ ˆ์ด์Šค ์—†์ด ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์„ฑ๋Šฅ: C/C++์— ๊ฒฌ์ค„๋งŒํ•œ ๋น ๋ฅธ ์†๋„๋ฅผ ์ž๋ž‘ํ•ด์š”. ์Šคํ”ผ๋“œ์˜ ๋ํŒ์™•! ๐ŸŽ๏ธ๐Ÿ’จ

Rust์˜ ์ด๋Ÿฐ ํŠน์ง•๋“ค ๋•Œ๋ฌธ์— ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด "์™€ ๋Œ€๋ฐ•! ์ด๊ฑฐ ์ง„์งœ ์ข‹์€๋ฐ?" ํ•˜๋ฉด์„œ ์—ด๊ด‘ํ•˜๊ณ  ์žˆ์–ด์š”. ํŠนํžˆ ์‹œ์Šคํ…œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‚˜ ์›น ๊ฐœ๋ฐœ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์ฃ .

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๋Ÿฌ๋ถ„, Rust์˜ ์ง„์งœ ๋งค๋ ฅ์€ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์žˆ์–ด์š”! ์ด๊ฒŒ ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ์˜ค๋Š˜ ํŒŒํ—ค์น  ์ฃผ์ œ์˜ˆ์š”. ํฅ๋ฏธ์ง„์ง„ํ•˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜†

2. ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ญ์•ผ? ๐Ÿคฏ

์ž, ์ด์ œ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ์ฐจ๋ก€์˜ˆ์š”. ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ํ•˜๋ฉด ๋ญ”๊ฐ€ ์–ด๋ ค์›Œ ๋ณด์ด์ฃ ? ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”. ์ œ๊ฐ€ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”!

๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ผ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”?

์ƒํ™ฉ ์˜ˆ์‹œ: ์—ฌ๋Ÿฌ๋ถ„์ด ๋ผ๋ฉด์„ ๋“์ด๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ณด์„ธ์š”. ๐Ÿœ

  1. ๋ฌผ์„ ๋“์ด๋Š” ๋™์•ˆ (๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„)
  2. ์ฑ„์†Œ๋ฅผ ์ฐ๊ณ  (๋‹ค๋ฅธ ์ž‘์—…)
  3. ๋ฌผ์ด ๋“์œผ๋ฉด ๋ฉด๊ณผ ์Šคํ”„๋ฅผ ๋„ฃ๊ณ  (๋‹ค์‹œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„)
  4. ๊ทธ ์‚ฌ์ด์— ๊ทธ๋ฆ‡๊ณผ ์ “๊ฐ€๋ฝ์„ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค. (๋˜ ๋‹ค๋ฅธ ์ž‘์—…)

์ด๋ ‡๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ์ด์—์š”!

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์˜ˆ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์›น ์„œ๋ฒ„์—์„œ ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ฃ . ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „์ฒด์ ์ธ ์„ฑ๋Šฅ์ด ํ›จ์”ฌ ์ข‹์•„์ ธ์š”. ๐Ÿ‘

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ! ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๊ณผ๋Š” ๋‹ฌ๋ผ์š”. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ CPU ์ฝ”์–ด๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ์ง€๋งŒ, ๋น„๋™๊ธฐ๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ๋„ ํšจ์œจ์ ์œผ๋กœ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์žฅ์ ์„ ์ •๋ฆฌํ•ด๋ณผ๊นŒ์š”?

  • ๋ฆฌ์†Œ์Šค ํšจ์œจ์„ฑ: CPU์™€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋ฐ˜์‘์„ฑ ํ–ฅ์ƒ: ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋™์ž‘ํ•ด์š”.
  • ํ™•์žฅ์„ฑ: ๋” ๋งŽ์€ ๋™์‹œ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ด์ œ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ญ”์ง€ ์ข€ ๊ฐ์ด ์˜ค์‹œ๋‚˜์š”? ๐Ÿ˜Š ๊ทธ๋Ÿผ ์ด์ œ Rust์—์„œ ์–ด๋–ป๊ฒŒ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”?

3. Rust์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ: Future์™€ async/await ๐Ÿ”ฎ

Rust์—์„œ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋…์ด ๋ฐ”๋กœ 'Future'์˜ˆ์š”. Future๋Š” ๋ฏธ๋ž˜์— ์™„๋ฃŒ๋  ์ž‘์—…์„ ๋‚˜ํƒ€๋‚ด๋Š” ํƒ€์ž…์ด์—์š”. ๋งˆ์น˜ "๋‚˜์ค‘์— ์ด ์ž‘์—…์ด ๋๋‚˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์ค„๊ฒŒ~"๋ผ๊ณ  ์•ฝ์†ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜์ฃ .

๊ทธ๋ฆฌ๊ณ  ์ด Future๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด Rust๋Š” 'async/await' ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•ด์š”. ์ด๊ฒŒ ๋ญ”์ง€ ์ฝ”๋“œ๋กœ ํ•œ๋ฒˆ ๋ณผ๊นŒ์š”?

async fn read_file(path: &str) -> Result<string std::io::error> {
    tokio::fs::read_to_string(path).await
}

async fn process_file() {
    let content = read_file("hello.txt").await.unwrap();
    println!("ํŒŒ์ผ ๋‚ด์šฉ: {}", content);
}

#[tokio::main]
async fn main() {
    process_file().await;
}
</string>

์šฐ์™€, ์ด ์ฝ”๋“œ ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ํ•˜๋‚˜์”ฉ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”!

  1. async fn: ์ด ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ผ๋Š” ๋œป์ด์—์š”. ์‹คํ–‰์ด ์ผ์‹œ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์–ด์š”.
  2. .await: Future๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋ผ๋Š” ์˜๋ฏธ์˜ˆ์š”. ๊ทธ๋™์•ˆ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”!
  3. #[tokio::main]: ์ด๊ฑด ๋ญ˜๊นŒ์š”? ๋ฐ”๋กœ Tokio ๋Ÿฐํƒ€์ž„์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋œป์ด์—์š”. ๊ณง ์ž์„ธํžˆ ์„ค๋ช…ํ• ๊ฒŒ์š”!

์ด async/await ๋ฌธ๋ฒ• ๋•๋ถ„์— ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋งˆ์น˜ ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜Ž

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ์˜๋ฌธ! "๊ทธ๋Ÿผ ์ด ๋น„๋™๊ธฐ ์ž‘์—…๋“ค์„ ๋ˆ„๊ฐ€ ๊ด€๋ฆฌํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ฑฐ์•ผ?" ๋ผ๊ณ  ๋ฌผ์œผ์‹ค ์ˆ˜ ์žˆ์–ด์š”. ๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ Tokio์˜ ๋“ฑ์žฅ์ž…๋‹ˆ๋‹ค! ์งœ์ž”~ ๐ŸŽ‰

4. Tokio: Rust์˜ ๋น„๋™๊ธฐ ๋Ÿฐํƒ€์ž„ ์˜์›… ๐Ÿฆธโ€โ™‚๏ธ

Tokio๋Š” Rust์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์˜ˆ์š”. ๋งˆ์น˜ ๋น„๋™๊ธฐ ์„ธ๊ณ„์˜ ์Šˆํผํžˆ์–ด๋กœ ๊ฐ™์ฃ ! ใ…‹ใ…‹ใ…‹

Tokio๊ฐ€ ํ•˜๋Š” ์ผ์„ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ด๋ณผ๊นŒ์š”?

  • ๋น„๋™๊ธฐ ์ž‘์—… ์Šค์ผ€์ค„๋ง: ์—ฌ๋Ÿฌ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์š”.
  • I/O ์ž‘์—… ์ฒ˜๋ฆฌ: ํŒŒ์ผ, ๋„คํŠธ์›Œํฌ ๋“ฑ์˜ ์ž…์ถœ๋ ฅ์„ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•ด์š”.
  • ํƒ€์ด๋จธ ๋ฐ ์‹œ๊ฐ„ ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต: ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋™์‹œ์„ฑ ๋„๊ตฌ ์ œ๊ณต: ์ฑ„๋„, ๋ฎคํ…์Šค ๋“ฑ์„ ๋น„๋™๊ธฐ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์ œ๊ณตํ•ด์š”.

Tokio๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •๋ง ์‰ฝ๊ฒŒ ๊ณ ์„ฑ๋Šฅ ๋น„๋™๊ธฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋งˆ๋ฒ•์ฒ˜๋Ÿผ์š”! โœจ

์ž, ์ด์ œ Tokio๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ๋ณผ๊นŒ์š”?

use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (mut socket, _) = listener.accept().await?;
        
        tokio::spawn(async move {
            let mut buf = [0; 1024];

            loop {
                let n = match socket.read(&mut buf).await {
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                if let Err(e) = socket.write_all(&buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}
</dyn>

์šฐ์™€, ์ด ์ฝ”๋“œ ์ข€ ๋ฉ‹์ง„๋ฐ์š”? ใ…‹ใ…‹ใ…‹ ์ด๊ฒŒ ๋ฐ”๋กœ Tokio๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์—์ฝ” ์„œ๋ฒ„์˜ˆ์š”. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€๋ฅผ ๊ทธ๋Œ€๋กœ ๋Œ๋ ค์ฃผ๋Š” ์„œ๋ฒ„์ฃ .

์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊นŒ์š”?

  1. TcpListener::bind(): 8080 ํฌํŠธ์—์„œ ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ ค์š”.
  2. listener.accept(): ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ์„ ๋ฐ›์•„๋“ค์—ฌ์š”.
  3. tokio::spawn(): ์ƒˆ๋กœ์šด ๋น„๋™๊ธฐ ํƒœ์Šคํฌ๋ฅผ ์ƒ์„ฑํ•ด์š”. ๊ฐ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”!
  4. socket.read()์™€ socket.write_all(): ๋น„๋™๊ธฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์”๋‹ˆ๋‹ค.

์ด ์ฝ”๋“œ ํ•˜๋‚˜๋กœ ์ˆ˜์ฒœ ๊ฐœ์˜ ๋™์‹œ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”! Tokio์˜ ํž˜์„ ๋Š๋ผ์‹œ๋‚˜์š”? ๐Ÿ˜Ž

5. Tokio์˜ ์ฃผ์š” ๊ธฐ๋Šฅ๋“ค: ๋น„๋™๊ธฐ์˜ ์Šค์œ„์Šค ์•„๋ฏธ ๋‚˜์ดํ”„ ๐Ÿ”ง

Tokio๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”. ๋งˆ์น˜ ์Šค์œ„์Šค ์•„๋ฏธ ๋‚˜์ดํ”„์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋„๊ตฌ๊ฐ€ ๋“ค์–ด์žˆ์ฃ ! ์ฃผ์š” ๊ธฐ๋Šฅ๋“ค์„ ์‚ดํŽด๋ณผ๊นŒ์š”?

5.1 ํƒœ์Šคํฌ (Tasks)

Tokio์˜ ํƒœ์Šคํฌ๋Š” ๊ฐ€๋ฒผ์šด ๋น„๋™๊ธฐ ์ž‘์—… ๋‹จ์œ„์˜ˆ์š”. tokio::spawn()์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํƒœ์Šคํฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ .

tokio::spawn(async {
    println!("์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” ์ƒˆ๋กœ์šด ํƒœ์Šคํฌ์˜ˆ์š”!");
});

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”์ธ ํƒœ์Šคํฌ์™€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ์ƒˆ๋กœ์šด ํƒœ์Šคํฌ๊ฐ€ ์ƒ์„ฑ๋ผ์š”. ๋ฉ‹์ง€์ฃ ? ๐Ÿ˜Ž

5.2 ์ฑ„๋„ (Channels)

์ฑ„๋„์€ ํƒœ์Šคํฌ ๊ฐ„์— ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ†ต์‹  ๋„๊ตฌ์˜ˆ์š”. Tokio๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์ฑ„๋„์„ ์ œ๊ณตํ•ด์š”.

use tokio::sync::mpsc;

#[tokio::main]
async fn main() {
    let (tx, mut rx) = mpsc::channel(32);

    tokio::spawn(async move {
        tx.send("์•ˆ๋…•ํ•˜์„ธ์š”!").await.unwrap();
    });

    if let Some(message) = rx.recv().await {
        println!("๋ฐ›์€ ๋ฉ”์‹œ์ง€: {}", message);
    }
}

์ด ์ฝ”๋“œ์—์„œ๋Š” mpsc(multi-producer, single-consumer) ์ฑ„๋„์„ ์‚ฌ์šฉํ–ˆ์–ด์š”. ์—ฌ๋Ÿฌ ์ƒ์‚ฐ์ž๊ฐ€ ํ•˜๋‚˜์˜ ์†Œ๋น„์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์ฃ .

5.3 ์‹œ๊ฐ„ ๊ด€๋ จ ๊ธฐ๋Šฅ (Time)

Tokio๋Š” ์‹œ๊ฐ„ ๊ด€๋ จ ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•ด์š”. ์ผ์ • ์‹œ๊ฐ„ ํ›„์— ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, ์ฃผ๊ธฐ์ ์œผ๋กœ ์ž‘์—…์„ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์ฃ .

use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
    println!("์ž ๊น๋งŒ ๊ธฐ๋‹ค๋ ค์ฃผ์„ธ์š”...");
    sleep(Duration::from_secs(2)).await;
    println!("2์ดˆ๊ฐ€ ์ง€๋‚ฌ์–ด์š”!");
}

์ด ์ฝ”๋“œ๋Š” 2์ดˆ ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•ด์š”. ๊ฐ„๋‹จํ•˜์ฃ ? ใ…‹ใ…‹ใ…‹

5.4 I/O ์ž‘์—…

Tokio๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ, ๋„คํŠธ์›Œํฌ ๋“ฑ์˜ I/O ์ž‘์—…์„ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”.

use tokio::fs::File;
use tokio::io::AsyncReadExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::error>> {
    let mut file = File::open("hello.txt").await?;
    let mut contents = String::new();
    file.read_to_string(&mut contents).await?;
    println!("ํŒŒ์ผ ๋‚ด์šฉ: {}", contents);
    Ok(())
}
</dyn>

์ด ์ฝ”๋“œ๋Š” ํŒŒ์ผ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฝ์–ด์˜ค๋Š” ์˜ˆ์ œ์˜ˆ์š”. ํŒŒ์ผ I/O๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”!

5.5 ๋™์‹œ์„ฑ ๋„๊ตฌ (Sync)

Tokio๋Š” Mutex, RwLock ๋“ฑ์˜ ๋™์‹œ์„ฑ ๋„๊ตฌ๋„ ์ œ๊ณตํ•ด์š”. ์ด๋“ค์€ ๋น„๋™๊ธฐ ํ™˜๊ฒฝ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์ฃ .

use tokio::sync::Mutex;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let counter = Arc::new(Mutex::new(0));

    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = tokio::spawn(async move {
            let mut lock = counter.lock().await;
            *lock += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.await.unwrap();
    }

    println!("์ตœ์ข… ์นด์šดํŠธ: {}", *counter.lock().await);
}

์ด ์˜ˆ์ œ์—์„œ๋Š” 10๊ฐœ์˜ ํƒœ์Šคํฌ๊ฐ€ ๋™์‹œ์— ์นด์šดํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ์š”. Mutex๋ฅผ ์‚ฌ์šฉํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ฃ .

์ด๋ ‡๊ฒŒ Tokio๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”. ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๋ชจ๋“  ๊ฒƒ์ด ์—ฌ๊ธฐ ๋‹ค ์žˆ๋‹ค๊ณ  ํ•ด๋„ ๊ณผ์–ธ์ด ์•„๋‹ˆ์ฃ !

6. Tokio๋ฅผ ํ™œ์šฉํ•œ ์‹ค์ „ ์˜ˆ์ œ: ์ฑ„ํŒ… ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ ๐Ÿ’ฌ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ํ™œ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ ์ฑ„ํŒ… ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ์ด ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด Tokio์˜ ๊ฐ•๋ ฅํ•จ์„ ์ง์ ‘ ์ฒดํ—˜ํ•ด๋ณด์„ธ์š”!

use tokio::net::{TcpListener, TcpStream};
use tokio::sync::broadcast;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};

#[tokio::main]
async fn main() {
    let listener = TcpListener::bind("localhost:8080").await.unwrap();
    let (tx, _rx) = broadcast::channel(10);

    loop {
        let (mut socket, addr) = listener.accept().await.unwrap();
        let tx = tx.clone();
        let mut rx = tx.subscribe();

        tokio::spawn(async move {
            let (reader, mut writer) = socket.split();
            let mut reader = BufReader::new(reader);
            let mut line = String::new();

            loop {
                tokio::select! {
                    result = reader.read_line(&mut line) => {
                        if result.unwrap() == 0 {
                            break;
                        }
                        tx.send((line.clone(), addr)).unwrap();
                        line.clear();
                    }
                    result = rx.recv() => {
                        let (msg, other_addr) = result.unwrap();
                        if addr != other_addr {
                            writer.write_all(msg.as_bytes()).await.unwrap();
                        }
                    }
                }
            }
        });
    }
}

์šฐ์™€, ์ด ์ฝ”๋“œ ์ •๋ง ๋Œ€๋‹จํ•˜์ง€ ์•Š๋‚˜์š”? ใ…‹ใ…‹ใ…‹ ํ•œ ๋ฒˆ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊นŒ์š”?

  1. TcpListener::bind(): 8080 ํฌํŠธ์—์„œ ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ ค์š”.
  2. broadcast::channel(): ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ์ฑ„๋„์„ ๋งŒ๋“ค์–ด์š”. ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ผ์š”.
  3. tokio::spawn(): ๊ฐ ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ํƒœ์Šคํฌ๋ฅผ ๋งŒ๋“ค์–ด์š”.
  4. socket.split(): ์†Œ์ผ“์„ ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ ์š”.
  5. tokio::select!: ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—… ์ค‘ ํ•˜๋‚˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์‹คํ–‰๋ผ์š”. ์—ฌ๊ธฐ์„œ๋Š” ๋ฉ”์‹œ์ง€ ์ฝ๊ธฐ์™€ ๋ฐ›๊ธฐ๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•ด์š”.

์ด ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋กœ ์ˆ˜์ฒœ ๋ช…์ด ๋™์‹œ์— ์ฑ„ํŒ…ํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์—ˆ์–ด์š”! Tokio์˜ ํž˜์„ ๋Š๋ผ์‹œ๋‚˜์š”? ๐Ÿ˜Ž

7. Tokio์˜ ์„ฑ๋Šฅ๊ณผ ํ™•์žฅ์„ฑ: ์ดˆ๊ณ ์† ๋น„๋™๊ธฐ์˜ ์„ธ๊ณ„ ๐Ÿš€

Tokio์˜ ์„ฑ๋Šฅ์€ ์ •๋ง ๋Œ€๋‹จํ•ด์š”. ์—ฌ๋Ÿฌ๋ถ„, ์ด๊ฑฐ ์•„์„ธ์š”? Tokio๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ๋„ ์ˆ˜๋งŒ ๊ฐœ์˜ ๋™์‹œ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”! ๐Ÿคฏ

์ด๋Ÿฐ ๋†€๋ผ์šด ์„ฑ๋Šฅ์˜ ๋น„๊ฒฐ์ด ๋ญ˜๊นŒ์š”? ๋ฐ”๋กœ ์ด๊ฑฐ์˜ˆ์š”:

  • ํšจ์œจ์ ์ธ ์ด๋ฒคํŠธ ๋ฃจํ”„: Tokio๋Š” ์šด์˜ ์ฒด์ œ์˜ ์ด๋ฒคํŠธ ํ†ต์ง€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•ด์š”.
  • Work-stealing ์Šค์ผ€์ค„๋Ÿฌ: ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ๊ฐ„์— ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ๋ถ„๋ฐฐํ•ด์š”.
  • ์ œ๋กœ-์ฝ”์ŠคํŠธ ์ถ”์ƒํ™”: Rust์˜ ๊ฐ•๋ ฅํ•œ ์ปดํŒŒ์ผ๋Ÿฌ ๋•๋ถ„์— ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๊ฑฐ์˜ ์—†์–ด์š”.
  • ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ: ๊ฐ ํƒœ์Šคํฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋งค์šฐ ์ ์–ด์š”.

์ด๋Ÿฐ ํŠน์ง•๋“ค ๋•๋ถ„์— Tokio๋Š” ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์—์„œ๋„ ์•„์ฃผ ์ž˜ ์ž‘๋™ํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, Discord๋ผ๋Š” ์œ ๋ช…ํ•œ ์ฑ„ํŒ… ํ”Œ๋žซํผ๋„ Tokio๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฑฐ ์•„์„ธ์š”? ๋Œ€๋ฐ•์ด์ฃ ? ใ…‹ใ…‹ใ…‹

๊ทธ๋ฆฌ๊ณ  Tokio์˜ ๋˜ ๋‹ค๋ฅธ ์žฅ์ ์€ ํ™•์žฅ์„ฑ์ด์—์š”. ์ž‘์€ ํ”„๋กœ์ ํŠธ์—์„œ ์‹œ์ž‘ํ•ด์„œ ์ ์  ํฐ ์‹œ์Šคํ…œ์œผ๋กœ ํ™•์žฅํ•ด ๋‚˜๊ฐ€๊ธฐ ์‰ฌ์›Œ์š”. Tokio์˜ ๊ฐ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ž˜ ์กฐํ™”๋ฅผ ์ด๋ฃจ๋ฉด์„œ๋„, ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.

Tokio๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋งˆ์น˜ ๋กœ์ผ“์ฒ˜๋Ÿผ ๋น ๋ฅด๊ณ , ๊ณ ๋ฌด์ค„์ฒ˜๋Ÿผ ์œ ์—ฐํ•ด์งˆ ๊ฑฐ์˜ˆ์š”! ๐Ÿš€๐Ÿงต

8. Tokio ์ƒํƒœ๊ณ„: ๋น„๋™๊ธฐ์˜ ๊ด‘ํ™œํ•œ ์šฐ์ฃผ ๐ŸŒŒ

Tokio๋Š” ๊ทธ ์ž์ฒด๋กœ๋„ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ์ฃผ๋ณ€์— ์ •๋ง ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์žˆ์–ด์š”. ๋งˆ์น˜ ํƒœ์–‘๊ณ„์˜ ํ–‰์„ฑ๋“ค์ฒ˜๋Ÿผ Tokio๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๋Œ๊ณ  ์žˆ์ฃ . ใ…‹ใ…‹ใ…‹ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์†Œ๊ฐœํ•ด๋“œ๋ฆด๊ฒŒ์š”!

8.1 Hyper

Hyper๋Š” Tokio ์œ„์— ๊ตฌ์ถ•๋œ ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•œ HTTP ๊ตฌํ˜„์ฒด์˜ˆ์š”. ์›น ์„œ๋ฒ„๋‚˜ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ ์ •๋ง ์œ ์šฉํ•ด์š”.