๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด/C++ ์‘์šฉ

std::thread์™€ std::async

by ์„œ์•„๋ž‘๐Ÿ˜ 2023. 1. 14.

 

 

โœ… ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ vs ๊ณผ์ œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ

 

work๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€ ์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” std::thread ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ทธ ๊ฐ์ฒด์—์„œ work๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด๊ณ , ์ด๋Š” ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜(thread-based) ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋˜ ํ•˜๋‚˜๋Š” work๋ฅผ std::async์— ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด๊ณ  ์ด๋Š” ๊ณผ์ œ ๊ธฐ๋ฐ˜(task-based) ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

 

int work();


std::thread t(work);

auto f = std::async(work);

 

์œ„ ์ฝ”๋“œ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ๋ณด์•˜์„ ๋•Œ, async๋ฅผ ์“ฐ๋ฉด work์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋ณด์ž…๋‹ˆ๋‹ค.(std::get์„ ํ†ตํ•ด ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)(thread๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.)

 

์ด๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋Œ€์ฒด๋กœ ๊ณผ์ œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฐฉ์‹์ด ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฐฉ์‹๋ณด๋‹ค ์šฐ์›”ํ•ฉ๋‹ˆ๋‹ค.

 

๊ณผ์ œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฐฉ์‹์€ ์ข€ ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์ถ”์ƒ์„ ์ฒดํ˜„ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋•๋ถ„์— ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์„ธ๋ถ€์ ์ธ ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ์—์„œ ๋ฒ—์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ๋งํ•˜๋ฉด ๊ณผ์ œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฐฉ์‹์€ ํ•˜๋“œ์›จ์–ด ์ž์›์„ ์ด์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์Šค๋ ˆ๋“œํ’€์„ ๊ด€๋ฆฌํ•ด์„œ ์Šค๋ ˆ๋“œ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ธฐ๋Šฅ์ด ๋“ค์–ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์šฐ๋ฆฌ๋Š” ๋‹จ์ง€ async๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

๋งŒ์•ฝ, ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ๋ณด๋‹ค ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“œ๋ ค๊ณ  ํ•˜๋ฉด ์–ด๋–จ๊ฒŒ ๋ ๊นŒ์š”?

 

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

 

 

โœ… ๋น„๋™๊ธฐ๊ฐ€ ํ•„์ˆ˜์ธ ๊ฒฝ์šฐ์—๋Š” std::launch::async

 

auto f = std::async(work);

auto f2 = std::async(std::launch::async | std::launch::deferred, work);

 

std::async์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ํ•จ์ˆ˜๋งŒ ๋„ฃ์–ด์ฃผ๋Š” ์ƒ์„ฑ์ž๋„ ์žˆ๊ณ , ์‹คํ–‰ ๋ฐฉ์นจ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์‹คํ–‰ ๋ฐฉ์นจ์—๋Š” std::launch::async, std::launch::deferred ๋“ฑ์ด ์žˆ๋Š”๋ฐ, ๋น„๋™๊ธฐ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” std::launch::async๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ํ•จ์ˆ˜๋งŒ ๋„ฃ๋Š” ์ธ์ž๊ฐ€ 1๊ฐœ์ธ ์ƒ์„ฑ์ž๋งŒ ํ˜ธ์ถœํ•ด๋„ ๋น„๋™๊ธฐ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ, ์‹คํ–‰ ๋ฐฉ์นจ์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด std::launch::async์™€ std::launch::deferred์„ OR๋กœ ๊ฒฐํ•ฉํ•œ ๋ฐฉ์นจ์ด ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ํ•จ์ˆ˜๋งŒ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€๋Š” std::async๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜๋„ ์žˆ๊ณ  ์•ˆ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๋™๊ธฐ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒŒ ๋ถ„๋ช…ํ•˜๋‹ค๋ฉด, std::launch::async๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

 

 

 

์ถœ์ฒ˜: Effective Modern C++

๋Œ“๊ธ€