๐Ÿš€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๊ณผ ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ค์ „ ์ ์šฉ๋ฒ• ๐Ÿš€

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๊ณผ ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ค์ „ ์ ์šฉ๋ฒ• ๐Ÿš€

 

 

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

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

์ด ๊ธ€์—์„œ๋Š” C++์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๋ช…ํ•  ๊ฑฐ์˜ˆ์š”. C++์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๊ณผ ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฑฐ๋“ ์š”. ๊ทธ๋ž˜์„œ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ์ž๋“ค ์‚ฌ์ด์—์„œ๋„ ์ธ๊ธฐ ๋งŒ์ ์ด์—์š”!

์ž, ๊ทธ๋Ÿผ ์ด์ œ๋ถ€ํ„ฐ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ์„ธ๊ณ„๋กœ ๋น ์ ธ๋ณผ๊นŒ์š”? ์ค€๋น„๋˜์…จ๋‚˜์š”? ๋ ˆ์ธ ๊ณ ~! ๐Ÿƒโ€โ™‚๏ธ๐Ÿ’จ

๐Ÿงต ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์ด ๋ญ๊ธธ๋ž˜? ๐Ÿงต

๋จผ์ € ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์ด ๋ญ”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”? ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์€ ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ ์ด์—์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ๋ถ„์ด ๋™์‹œ์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ผ์„ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”!

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์š”๋ฆฌ๋ฅผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์„ธ์š”. ๋ฐฅ์„ ์ง“๊ณ , ๊ตญ์„ ๋“์ด๊ณ , ๋ฐ˜์ฐฌ์„ ๋งŒ๋“œ๋Š” ๊ฑธ ๋ชจ๋‘ ๋™์‹œ์— ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ›จ์”ฌ ํšจ์œจ์ ์ด๊ฒ ์ฃ ? ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๋„ ์ด์™€ ๋น„์Šทํ•ด์š”!

๐Ÿณ ์š”๋ฆฌ๋กœ ๋ณด๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ

  • ๋ฐฅ ์ง“๊ธฐ = ์Šค๋ ˆ๋“œ 1
  • ๊ตญ ๋“์ด๊ธฐ = ์Šค๋ ˆ๋“œ 2
  • ๋ฐ˜์ฐฌ ๋งŒ๋“ค๊ธฐ = ์Šค๋ ˆ๋“œ 3

์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋ฉด, ์ „์ฒด์ ์ธ ์š”๋ฆฌ ์‹œ๊ฐ„์ด ์ค„์–ด๋“ค๊ฒ ์ฃ ? ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ์žฅ์ ์ด ๋ฐ”๋กœ ์ด๊ฑฐ์˜ˆ์š”!

๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ! ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘ ๋ช…์ด ๋™์‹œ์— ๊ฐ™์€ ์žฌ๋ฃŒ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์ถฉ๋Œ์ด ์ผ์–ด๋‚˜๊ฒ ์ฃ ? ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๊ฒฝ์Ÿ ์กฐ๊ฑด(Race Condition)์ด๋ผ๊ณ  ํ•ด์š”. ์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š”์ง€๋„ ๋‚˜์ค‘์— ์ž์„ธํžˆ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”!

์ž, ์ด์ œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ์•Œ์•˜์œผ๋‹ˆ, ๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€๋ณผ๊นŒ์š”? ๐ŸŠโ€โ™‚๏ธ

๐Ÿ” C++์—์„œ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๊ตฌํ˜„ํ•˜๊ธฐ ๐Ÿ”

C++์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์–ด์š”. ํ•˜์ง€๋งŒ ์˜ค๋Š˜์€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” C++11์˜ ์Šค๋ ˆ๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์„ค๋ช…ํ• ๊ฒŒ์š”.

๋จผ์ €, ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ์•Œ์•„๋ณผ๊นŒ์š”? C++์—์„œ๋Š” std::thread ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์•„์ฃผ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ๋ณผ๊ฒŒ์š”!

#include <iostream>
#include <thread>

void hello() {
    std::cout << "์•ˆ๋…•ํ•˜์„ธ์š”! ์ €๋Š” ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ์˜ˆ์š”!" << std::endl;
}

int main() {
    std::thread t(hello);  // ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
    t.join();  // ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ
    return 0;
}

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด "์•ˆ๋…•ํ•˜์„ธ์š”! ์ €๋Š” ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ์˜ˆ์š”!"๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋ผ์š”. ์‹ ๊ธฐํ•˜์ฃ ? ๐Ÿ˜ฒ

์—ฌ๊ธฐ์„œ std::thread t(hello); ๋ถ€๋ถ„์ด ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๊ทธ๋ฆฌ๊ณ  t.join();์€ ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋ผ๋Š” ๋œป์ด์—์š”.

๐Ÿšจ ์ฃผ์˜์‚ฌํ•ญ

์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ join()์ด๋‚˜ detach()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ด์š”! ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋น„์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์–ด์š”. join()์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ , detach()๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€ ๋ถ„๋ฆฌํ•ด์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ฒŒ ํ•ด์š”.

์ด์ œ ์ข€ ๋” ๋ณต์žกํ•œ ์˜ˆ์ œ๋ฅผ ๋ณผ๊นŒ์š”? ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ์˜ˆ์š”.

#include <iostream>
#include <thread>
#include <vector>

void worker(int id) {
    std::cout << "์ž‘์—…์ž " << id << " ์ผํ•˜๋Š” ์ค‘..." << std::endl;
    // ์—ฌ๊ธฐ์— ์‹ค์ œ ์ž‘์—… ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”
}

int main() {
    std::vector<std::thread> threads;
    
    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::thread(worker, i));
    }
    
    for (auto& t : threads) {
        t.join();
    }
    
    std::cout << "๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!" << std::endl;
    return 0;
}

์ด ์ฝ”๋“œ๋Š” 5๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ worker ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ด์š”. ๊ฐ worker๋Š” ์ž์‹ ์˜ ID๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ์ฃ . ์‹ค์ œ๋กœ๋Š” ์ด ๋ถ€๋ถ„์— ๋” ๋ณต์žกํ•œ ์ž‘์—…์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์–ด์š”.

์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•  ์ ์€ ๋ฒกํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฑฐ์˜ˆ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋งŽ์€ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์š”.

์ž, ์ด์ œ ๊ธฐ๋ณธ์ ์ธ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ์•Œ์•˜์–ด์š”. ๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹ˆ์—์š”! ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฌธ์ œ์— ๋ถ€๋”ชํž ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ ์ค‘์—์„œ ๊ฐ€์žฅ ํ”ํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ(Data Race)์ด์—์š”. ์ด๊ฒŒ ๋ญ”์ง€ ๋‹ค์Œ ์„น์…˜์—์„œ ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊ฒŒ์š”! ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ

๐Ÿšฆ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ(Data Race)๊ณผ ๋™๊ธฐํ™” ๐Ÿšฆ

์ž, ์ด์ œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ๊ฐ€์žฅ ํฐ ํ•จ์ •์ธ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์ด ๋ญ”์ง€ ์•„์„ธ์š”? ์‰ฝ๊ฒŒ ๋งํ•ด์„œ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•ด์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋Š” ์ƒํ™ฉ์„ ๋งํ•ด์š”.

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

๐Ÿงน ์ฒญ์†Œ๋กœ ๋ณด๋Š” ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ

  • ๋ฐฉ = ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ
  • ์ฒญ์†Œํ•˜๋Š” ์นœ๊ตฌ๋“ค = ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ
  • ์น˜์šฐ๋ ค๋Š” ๋ฌผ๊ฑด = ๊ณต์œ  ๋ฐ์ดํ„ฐ

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ํ•˜๋ฉด, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์–ด์š”!

๊ทธ๋Ÿผ ์ด๋Ÿฐ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ ๋™๊ธฐํ™”(Synchronization)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ์š”! ๋™๊ธฐํ™”๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ, ์ถฉ๋Œ ์—†์ด ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด์—์š”.

C++์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋™๊ธฐํ™” ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ด์š”. ๊ทธ ์ค‘์—์„œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ฒƒ์ด ๋ฐ”๋กœ std::mutex์˜ˆ์š”. mutex๋Š” "mutual exclusion"์˜ ์ค„์ž„๋ง๋กœ, ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ์˜๋ฏธํ•ด์š”. ์ฆ‰, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฑฐ์ฃ .

mutex๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ๋ณผ๊ฒŒ์š”:

#include <iostream>
#include <thread>
#include <mutex>

int shared_value = 0;
std::mutex mtx;

void increment() {
    for (int i = 0; i < 1000000; ++i) {
        mtx.lock();
        ++shared_value;
        mtx.unlock();
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    
    t1.join();
    t2.join();
    
    std::cout << "์ตœ์ข… ๊ฐ’: " << shared_value << std::endl;
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ shared_value๋Š” ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ˆ์š”. mtx.lock()๊ณผ mtx.unlock() ์‚ฌ์ด์— ์žˆ๋Š” ์ฝ”๋“œ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ฃ !

ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•  ์ ์ด ์žˆ์–ด์š”. lock()์„ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ unlock()์„ ํ˜ธ์ถœํ•ด์•ผ ํ•ด์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์ด ์˜์›ํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์–ด์š”. ์ด๋Ÿฐ ์ƒํ™ฉ์„ ๊ต์ฐฉ ์ƒํƒœ(Deadlock)๋ผ๊ณ  ํ•ด์š”.

๊ทธ๋ž˜์„œ C++์—์„œ๋Š” ๋” ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ std::lock_guard๋ฅผ ์ œ๊ณตํ•ด์š”. ์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ unlock์„ ์ฒ˜๋ฆฌํ•ด์ค˜์„œ ์‹ค์ˆ˜๋กœ unlock์„ ๋นผ๋จน๋Š” ์ผ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

#include <iostream>
#include <thread>
#include <mutex>

int shared_value = 0;
std::mutex mtx;

void increment() {
    for (int i = 0; i < 1000000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        ++shared_value;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    
    t1.join();
    t2.join();
    
    std::cout << "์ตœ์ข… ๊ฐ’: " << shared_value << std::endl;
    return 0;
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด lock_guard ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์ž๋™์œผ๋กœ lock์ด ๊ฑธ๋ฆฌ๊ณ , ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ ์ž๋™์œผ๋กœ unlock์ด ๋ผ์š”. ํ›จ์”ฌ ์•ˆ์ „ํ•˜๊ณ  ํŽธ๋ฆฌํ•˜์ฃ ? ๐Ÿ˜Ž

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

๐ŸŽญ ๊ณ ๊ธ‰ ๋™์‹œ์„ฑ ๊ธฐ๋ฒ•: ์กฐ๊ฑด ๋ณ€์ˆ˜์™€ ์›์ž์  ์—ฐ์‚ฐ ๐ŸŽญ

์ž, ์ด์ œ ์ข€ ๋” ๊ณ ๊ธ‰์Šค๋Ÿฌ์šด ๋™์‹œ์„ฑ ๊ธฐ๋ฒ•๋“ค์„ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด ๊ธฐ๋ฒ•๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ํšจ์œจ์ ์ด๊ณ  ์•ˆ์ „ํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๋ ˆ์ธ ๊ณ ! ๐Ÿƒโ€โ™‚๏ธ๐Ÿ’จ

1. ์กฐ๊ฑด ๋ณ€์ˆ˜ (Condition Variable)

์กฐ๊ฑด ๋ณ€์ˆ˜๋Š” ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ๋™๊ธฐํ™” ๋„๊ตฌ์˜ˆ์š”. ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋  ๋•Œ๊นŒ์ง€ ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ€๊ธฐ์‹œํ‚ค๊ณ , ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜๋ฉด ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๋Š” ์—ญํ• ์„ ํ•ด์š”.

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

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

std::queue<int> data_queue;
std::mutex mtx;
std::condition_variable cv;

void producer() {
    for (int i = 0; i < 10; ++i) {
        {
            std::lock_guard<std::mutex> lock(mtx);
            data_queue.push(i);
            std::cout << "์ƒ์‚ฐ: " << i << std::endl;
        }
        cv.notify_one();  // ์†Œ๋น„์ž์—๊ฒŒ ์•Œ๋ฆผ
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, []{ return !data_queue.empty(); });  // ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
        int value = data_queue.front();
        data_queue.pop();
        std::cout << "์†Œ๋น„: " << value << std::endl;
        if (value == 9) break;  // ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ›„ ์ข…๋ฃŒ
    }
}

int main() {
    std::thread prod(producer);
    std::thread cons(consumer);
    
    prod.join();
    cons.join();
    
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ cv.wait()๋Š” ์†Œ๋น„์ž ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ€๊ธฐ์‹œํ‚ค๊ณ , cv.notify_one()์€ ๋Œ€๊ธฐ ์ค‘์ธ ์†Œ๋น„์ž ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๋Š” ์—ญํ• ์„ ํ•ด์š”. coolํ•˜์ฃ ? ๐Ÿ˜Ž

2. ์›์ž์  ์—ฐ์‚ฐ (Atomic Operations)

์›์ž์  ์—ฐ์‚ฐ์€ ์ค‘๊ฐ„์— ๋Š๊ธฐ์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ์— ์™„๋ฃŒ๋˜๋Š” ์—ฐ์‚ฐ์„ ๋งํ•ด์š”. C++์—์„œ๋Š” std::atomic ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•ด์„œ ์›์ž์  ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

์›์ž์  ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋ฉด mutex๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”. ํŠนํžˆ ๊ฐ„๋‹จํ•œ ์นด์šดํ„ฐ๋‚˜ ํ”Œ๋ž˜๊ทธ ๋ณ€์ˆ˜์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ผ์š”.

#include <iostream>
#include <thread>
#include <atomic>

std::atomic<int> counter(0);

void increment() {
    for (int i = 0; i < 1000000; ++i) {
        ++counter;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    
    t1.join();
    t2.join();
    
    std::cout << "์ตœ์ข… ์นด์šดํ„ฐ ๊ฐ’: " << counter << std::endl;
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ counter๋Š” ์›์ž์  ๋ณ€์ˆ˜์˜ˆ์š”. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•ด๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ๋ฉ‹์ง€์ฃ ? ๐Ÿ‘

๐Ÿš€ ์›์ž์  ์—ฐ์‚ฐ vs Mutex

  • ์›์ž์  ์—ฐ์‚ฐ: ๊ฐ„๋‹จํ•œ ์—ฐ์‚ฐ์— ์ ํ•ฉ, ๋” ๋น ๋ฆ„
  • Mutex: ๋ณต์žกํ•œ ์—ฐ์‚ฐ์ด๋‚˜ ๊ธด ์ฝ”๋“œ ๋ธ”๋ก์— ์ ํ•ฉ, ๋” ์œ ์—ฐํ•จ

์ƒํ™ฉ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด์š”!

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

๐ŸŽจ ์‹ค์ „ ํ”„๋กœ์ ํŠธ: ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๊ธฐ ๐ŸŽจ

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

์ด ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์–ด์š”:

  • ์Šค๋ ˆ๋“œ ํ’€ ๊ตฌํ˜„ํ•˜๊ธฐ
  • ์ž‘์—… ํ ๋งŒ๋“ค๊ธฐ
  • ์กฐ๊ฑด ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•œ ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™”
  • ์›์ž์  ์—ฐ์‚ฐ์„ ์ด์šฉํ•œ ์ž‘์—… ์ง„ํ–‰ ์ƒํ™ฉ ์ถ”์ 

์ž, ๊ทธ๋Ÿผ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ๋ณผ๊นŒ์š”?

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>
#include <atomic>
#include <functional>

class ThreadPool {
private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queue_mutex;
    std::condition_variable condition;
    std::atomic<bool> stop;
    std::atomic<int> active_tasks;

public:
    ThreadPool(size_t threads) : stop(false), active_tasks(0) {
        for(size_t i = 0; i < threads; ++i)
            workers.emplace_back(
                [this] {
                    for(;;) {
                        std::function<void()> task;
                        {
                            std::unique_lock<std::mutex> lock(this->queue_mutex);
                            this->condition.wait(lock,
                                [this]{ return this->stop || !this->tasks.empty(); });
                            if(this->stop && this->tasks.empty())
                                return;
                            task = std::move(this->tasks.front());
                            this->tasks.pop();
                        }
                        ++active_tasks;
                        task();
                        --active_tasks;
                    }
                }
            );
    }

    template<class F>
    void enqueue(F&& f) {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            tasks.emplace(std::forward<F>(f));
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for(std::thread &worker: workers)
            worker.join();
    }

    int get_active_tasks() const {
        return active_tasks;
    }
};

// ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ํ•จ์ˆ˜
void process_image(int image_id) {
    std::cout << "์ด๋ฏธ์ง€ " << image_id << " ์ฒ˜๋ฆฌ ์‹œ์ž‘" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));  // ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
    std::cout << "์ด๋ฏธ์ง€ " << image_id << " ์ฒ˜๋ฆฌ ์™„๋ฃŒ" << std::endl;
}

int main() {
    ThreadPool pool(4);  // 4๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋กœ ํ’€ ์ƒ์„ฑ
    std::atomic<int> completed_tasks(0);
    int total_tasks = 10;

    for(int i = 0; i < total_tasks; ++i) {
        pool.enqueue([i, &completed_tasks]{
            process_image(i);
            ++completed_tasks;
        });
    }

    // ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
    while(completed_tasks < total_tasks) {
        std::cout << "์ง„ํ–‰ ์ƒํ™ฉ: " << completed_tasks << "/" << total_tasks 
                  << " (ํ™œ์„ฑ ์ž‘์—…: " << pool.get_active_tasks() << ")" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    std::cout << "๋ชจ๋“  ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ์™„๋ฃŒ!" << st  d::endl;

    return 0;
}

์™€์šฐ! ๊ฝค ๊ธด ์ฝ”๋“œ์ฃ ? ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊ฒŒ์š”. ๐Ÿ˜Š

1. ThreadPool ํด๋ž˜์Šค

์ด ํด๋ž˜์Šค๋Š” ์Šค๋ ˆ๋“œ ํ’€์„ ๊ตฌํ˜„ํ•ด์š”. ์Šค๋ ˆ๋“œ ํ’€์€ ๋ฏธ๋ฆฌ ์ผ์ • ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‘๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์ž‘์—…์„ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์ด์—์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ๋งค๋ฒˆ ์ƒ์„ฑํ•˜๊ณ  ์†Œ๋ฉธ์‹œํ‚ค๋Š” ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

  • workers: ์‹ค์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์Šค๋ ˆ๋“œ๋“ค์ด์—์š”.
  • tasks: ์ˆ˜ํ–‰ํ•  ์ž‘์—…๋“ค์„ ์ €์žฅํ•˜๋Š” ํ์˜ˆ์š”.
  • queue_mutex์™€ condition: ์ž‘์—… ํ์— ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•˜๊ณ , ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋ผ์š”.
  • stop: ์Šค๋ ˆ๋“œ ํ’€์„ ์ข…๋ฃŒํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”Œ๋ž˜๊ทธ์˜ˆ์š”.
  • active_tasks: ํ˜„์žฌ ์ฒ˜๋ฆฌ ์ค‘์ธ ์ž‘์—…์˜ ์ˆ˜๋ฅผ ์ถ”์ ํ•ด์š”.

2. process_image ํ•จ์ˆ˜

์ด ํ•จ์ˆ˜๋Š” ์‹ค์ œ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ด์š”. ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์—ฌ๊ธฐ์— ์ง„์งœ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ๋“ค์–ด๊ฐˆ ๊ฑฐ์˜ˆ์š”.

3. main ํ•จ์ˆ˜

๋ฉ”์ธ ํ•จ์ˆ˜์—์„œ๋Š” ThreadPool์„ ์ƒ์„ฑํ•˜๊ณ , ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ์ž‘์—…์„ ํ์— ์ถ”๊ฐ€ํ•ด์š”. ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ถœ๋ ฅํ•ด์š”.

๐ŸŽจ ์ด ํ”„๋กœ๊ทธ๋žจ์˜ ์žฅ์ 

  • ์—ฌ๋Ÿฌ ์ด๋ฏธ์ง€๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ๋น ๋ฅธ ์ฒ˜๋ฆฌ ์†๋„
  • ์Šค๋ ˆ๋“œ ํ’€์„ ์‚ฌ์šฉํ•ด ํšจ์œจ์ ์ธ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ
  • ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ง„ํ–‰ ์ƒํ™ฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ด๋ฏธ์ง€๊ฐ€ ๋™์‹œ์— ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”. ์ง„ํ–‰ ์ƒํ™ฉ๋„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์ฃ . ์ •๋ง ๋ฉ‹์ง€์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜ƒ

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

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์—ฌํ–‰์ด ๊ฑฐ์˜ ๋๋‚˜๊ฐ€๊ณ  ์žˆ์–ด์š”. ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค๊ณผ ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๐Ÿค“

๐ŸŽ“ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋งˆ์Šคํ„ฐ๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ํŒ๊ณผ ์ฃผ์˜์‚ฌํ•ญ ๐ŸŽ“

์—ฌ๋Ÿฌ๋ถ„, ์ •๋ง ๋Œ€๋‹จํ•ด์š”! ์ง€๊ธˆ๊นŒ์ง€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ๊ธฐ๋ณธ๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ๊นŒ์ง€ ๋ชจ๋‘ ๋ฐฐ์› ์–ด์š”. ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋งˆ์Šคํ„ฐ์— ํ•œ ๊ฑธ์Œ ๋” ๊ฐ€๊นŒ์›Œ์กŒ์–ด์š”. ํ•˜์ง€๋งŒ ์•„์ง ๋์ด ์•„๋‹ˆ์—์š”! ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค์ด ์žˆ์–ด์š”. ํ•จ๊ป˜ ์•Œ์•„๋ณผ๊นŒ์š”? ๐Ÿง

1. ๋ฐ๋“œ๋ฝ(Deadlock) ์กฐ์‹ฌํ•˜๊ธฐ

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

๋ฐ๋“œ๋ฝ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•:

  • ํ•ญ์ƒ ๊ฐ™์€ ์ˆœ์„œ๋กœ ๋ฝ์„ ํš๋“ํ•˜์„ธ์š”.
  • ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด std::lock() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ ๋ฎคํ…์Šค๋ฅผ ํ•œ ๋ฒˆ์— ์ž ๊ทธ์„ธ์š”.
  • ๋ฝ์„ ์˜ค๋ž˜ ์žก๊ณ  ์žˆ์ง€ ๋งˆ์„ธ์š”. ํ•„์š”ํ•œ ๋ถ€๋ถ„์—์„œ๋งŒ ์งง๊ฒŒ ์‚ฌ์šฉํ•˜์„ธ์š”.

2. ๊ฒฝ์Ÿ ์กฐ๊ฑด(Race Condition) ์ฃผ์˜ํ•˜๊ธฐ

๊ฒฝ์Ÿ ์กฐ๊ฑด์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ๋™์‹œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋กœ ์ธํ•ด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์ฃ .

๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•:

  • ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ๋Š” ํ•ญ์ƒ ์ ์ ˆํ•œ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜(๋ฎคํ…์Šค, ์›์ž์  ์—ฐ์‚ฐ ๋“ฑ)์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ์ €์žฅ์†Œ๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ๊ณต์œ ๋ฅผ ์ตœ์†Œํ™”ํ•˜์„ธ์š”.

3. ๊ณผ๋„ํ•œ ๋™๊ธฐํ™” ํ”ผํ•˜๊ธฐ

๋™๊ธฐํ™”๋Š” ํ•„์š”ํ•˜์ง€๋งŒ, ๋„ˆ๋ฌด ๊ณผ๋„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”. ๋ชจ๋“  ๊ฒƒ์„ ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ •๋ง ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”.

ํšจ์œจ์ ์ธ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ํŒ:

  • ๊ฐ€๋Šฅํ•œ ํ•œ ์ž‘์€ ๋ฒ”์œ„์—์„œ๋งŒ ๋ฝ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • ์ฝ๊ธฐ ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ std::shared_mutex๋ฅผ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.
  • ๋‹จ์ˆœํ•œ ์นด์šดํ„ฐ๋‚˜ ํ”Œ๋ž˜๊ทธ์—๋Š” std::atomic์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

4. ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ ๊ณ ๋ คํ•˜๊ธฐ

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ชจ๋“  ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค๊ฐ€ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ์ง€ ๊ณ ๋ คํ•ด์•ผ ํ•ด์š”. ํŠนํžˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ์ง€ ๊ผญ ํ™•์ธํ•˜์„ธ์š”.

5. ํ…Œ์ŠคํŠธ์™€ ๋””๋ฒ„๊น…

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์€ ํ…Œ์ŠคํŠธ์™€ ๋””๋ฒ„๊น…์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์–ด์š”. ๋™์‹œ์„ฑ ๋ฌธ์ œ๋Š” ์žฌํ˜„ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ฑฐ๋“ ์š”.

ํšจ๊ณผ์ ์ธ ํ…Œ์ŠคํŠธ์™€ ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ํŒ:

  • ์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ฐพ์œผ์„ธ์š”.
  • ์ •์  ๋ถ„์„ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•ด ์ž ์žฌ์ ์ธ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐœ๊ฒฌํ•˜์„ธ์š”.
  • ๋กœ๊น…์„ ํ™œ์šฉํ•ด ์Šค๋ ˆ๋“œ ๋™์ž‘์„ ์ถ”์ ํ•˜์„ธ์š”.

๐Ÿ’ก ์ตœ์ข… ์กฐ์–ธ

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ํ•ญ์ƒ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ์—์š”. ๋‹จ์ˆœํ•œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์˜คํžˆ๋ ค ๋ณต์žก์„ฑ๋งŒ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์ด ์ •๋ง ํ•„์š”ํ•œ์ง€, ๊ทธ๋ฆฌ๊ณ  ์ด์ ์ด ๋ณต์žก์„ฑ์„ ์ƒ์‡„ํ•  ๋งŒํผ ํฐ์ง€ ํ•ญ์ƒ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.

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

๐ŸŽ‰ ๋งˆ๋ฌด๋ฆฌ: ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋งˆ์Šคํ„ฐ์˜ ๊ธธ ๐ŸŽ‰

์™€์šฐ! ์ •๋ง ๊ธด ์—ฌ์ •์ด์—ˆ์ฃ ? ์—ฌ๋Ÿฌ๋ถ„, ์ •๋ง ๋Œ€๋‹จํ•ด์š”! ๐Ÿ‘๐Ÿ‘๐Ÿ‘

์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ A๋ถ€ํ„ฐ Z๊นŒ์ง€ ๋ชจ๋“  ๊ฒƒ์„ ์‚ดํŽด๋ดค์–ด์š”. ๊ธฐ๋ณธ ๊ฐœ๋…๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ๊นŒ์ง€, ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€๊นŒ์ง€ ๋ฐฐ์› ์ฃ . ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ๊ฐ•๋ ฅํ•œ ํž˜์„ ์ž์œ ์ž์žฌ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ์‹ค๋ ฅ์ž๊ฐ€ ๋˜์—ˆ์–ด์š”!

ํ•˜์ง€๋งŒ ๊ธฐ์–ตํ•˜์„ธ์š”. ๋ชจ๋“  ํž˜์—๋Š” ์ฑ…์ž„์ด ๋”ฐ๋ฅด๋Š” ๋ฒ•์ด์—์š”. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์€ ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ง€๋งŒ, ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ํ•ญ์ƒ ์‹ ์ค‘ํ•˜๊ฒŒ, ๊ทธ๋ฆฌ๊ณ  ํ˜„๋ช…ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.

์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋”ฉ ์—ฌ์ •์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์ด ํฐ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ผ์š”. ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ๋” ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š” ๋ฐ ์ด ์ง€์‹์ด ํฐ ํž˜์ด ๋  ๊ฑฐ์˜ˆ์š”.

๋งˆ์ง€๋ง‰์œผ๋กœ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ธ๊ณ„๋Š” ๋Š์ž„์—†์ด ๋ณ€ํ™”ํ•˜๊ณ  ๋ฐœ์ „ํ•œ๋‹ค๋Š” ๊ฑธ ์žŠ์ง€ ๋งˆ์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ๋ฐฐ์šด ์ด ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ, ์•ž์œผ๋กœ๋„ ๊ณ„์†ํ•ด์„œ ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ฐฐ์šฐ๊ณ  ๋„์ „ํ•˜์„ธ์š”. ๊ทธ๊ฒŒ ๋ฐ”๋กœ ์ง„์ •ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์ž์„ธ๋‹ˆ๊นŒ์š”! ๐Ÿ˜‰

์ž, ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค ์‹œ๊ฐ„์ด์—์š”. ์–ด๋–ค ๋ฉ‹์ง„ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์ •๋ง ๊ธฐ๋Œ€๋˜๋„ค์š”! ํ™”์ดํŒ…! ๐Ÿš€๐ŸŒŸ

๐ŸŽ“ ์—ฌ๋Ÿฌ๋ถ„์˜ ๋‹ค์Œ ๋‹จ๊ณ„

  • ๋ฐฐ์šด ๋‚ด์šฉ์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด๋ณด์„ธ์š”.
  • ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ณ  ํ† ๋ก ํ•ด๋ณด์„ธ์š”.
  • ์ตœ์‹  C++ ํ‘œ์ค€์˜ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๋“ค์„ ๊ณ„์†ํ•ด์„œ ํ•™์Šตํ•˜์„ธ์š”.
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ ๋””๋ฒ„๊น… ๊ธฐ์ˆ ์„ ๋” ๊นŠ์ด ๊ณต๋ถ€ํ•ด๋ณด์„ธ์š”.

์—ฌ๋Ÿฌ๋ถ„์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋งˆ์Šคํ„ฐ ์—ฌ์ •์„ ์‘์›ํ•ฉ๋‹ˆ๋‹ค! ์–ธ์ œ๋‚˜ ์ฆ๊ฒ๊ฒŒ ์ฝ”๋”ฉํ•˜์„ธ์š”! ๐Ÿ˜„๐Ÿ‘