ใ์ถ์ฒ. ์์ํ์! C++17 ํ๋ก๊ทธ๋๋ฐ (๋ฐํ์ฌ ์ง์)ใ
์์ํ๊ธฐ ์ ๋๊ธฐ์ ๋น๋๊ธฐ์ ๋ํด์ ๋จผ์ ์์๋ณด์!
Asynchronous(๋น๋๊ธฐ) Synchronous(๋๊ธฐ) ๋ฐ์๋ ์ด๋ ค์ ๋ณด์ด๋ ๋๊ธฐ, ๋น๋๊ธฐ ์ผ๋จ ๋ง์ ํ ์ ์์ด์ผ ํ๋.. ๋ฒ์ญ๊ธฐ์ ๋๋ ค ์ฝ์ด์ฃผ๋๋ฐ๋ก ํ ๋ฒ ์ ์ด๋ณด๊ฒ ์ต๋๋ค.
Synchronous-> siNGkrษnษs(์จ-์ธ!ํฌ๋ก๋์ค)
Asynchronous->ฤหsiNGkrษnษs(์์ด ์จ-์ธ!ํฌ๋ก๋์ค)
์ด๋ฐ์์ผ๋ก ๋ฐ์ํด์ฃผ๊ณ ์์ต๋๋ค. ์์ ๋ก์๋ค.. ๋ฉด์ ์์ ๋ฌผ์ด๋ณด๋ฉด ์์๋ฃ๊ธด ํด์ผํ๋๊น (T_T)/
์ด์ ์ด ๋์ ์ฐจ์ด์ ๊ณผ ์ง๋ ๋ป์ ์์๋ณด์!
๊ฒฐ๊ตญ ๋น๋๊ธฐ์ ์คํ์ ํ๊ณ ์ถ์ ์ผ์, ์ด๋ ํ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ์ฐ๋ ๋๋ฅผ ํตํด ์ฒ๋ฆฌํด์ ๋ฐ์๋ด๋ ๊ณผ์ ์ด๋ค.
c++์์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋์์ฃผ๋ ํด๋์ค์ ํจ์๋ฅผ ์์๋ณด๋ ๊ณผ์ ์ ๊ณต๋ถํ๊ณ ์์ฉํด๋ณด์.
โ future ํด๋์ค : "์์ฒด์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑ์ํค๋ ์ผ๋ฐ ์์ฑ์๋ฅผ ์ ๊ณตํ์ง ์๋๋ค."
furture ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ async() ํจ์๋ ๋ ์ข ๋ฅ๋ฅผ ์ ๊ณตํ๋ค.
- async ( Function&& f, Args&& ... args ) : <futrue>
- async ( std::lauch policy, Function&& f, Args&&... args ) : <future>
async()ํจ์์์ ์ฌ์ฉํ๋ ์ธ์ rvalue ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๋ค.
์์ฆ ์ค๋ ๋๋ณด๋ค ์ ํธ๋๋ฉฐ, std::future๊ฐ์ฒด๋ก ๋ฆฌํด์ ํ๋ค. ๋ฆฌํด ๊ฐ์ ํ์ฌ ๋ฐ์ง ๋ชปํ๋ ๊ฐ ์ผ์๋ ์์์ ๋ฏธ๋์ ๋ฐ์ ์๋ ์์์ ์ผ๋ํด๋๊ณ ๊ธฐ๋ค๋ฆฐ๋ค. ๋ฆฌํด๊ฐ์ ๋ฐ์ผ๋ฉด future.get()์ ์ํํ๋ค.
์ค๋ ๋๋ฒ์ ๊ณผ asyncํจ์ ์ฌ์ฉ๋ฒ์ ์ผ๋ก ๋๋ ์ ๋ณด์!
์ฝ๋ ์ฐธ์กฐ๋ ์์ํ์! C++17 ํ๋ก๊ทธ๋๋ฐ ๋์๋ฅผ ํตํด ์ฝ๋๋ฅผ ์์ฑํ์๋ค.
#include <thread>
#include <iostream>
#include <chrono>
#include <numeric>
#include <vector>
std::vector<std::thread> workers(std::vector<int>& , std::vector<int>*);
void accumulate_block_worker(int*, size_t, int*);
int main(void)
{
std::vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
std::vector<int> result(2, 0);
std::vector<std::thread> threads = workers(v, &result);
for (auto& t : threads)
{
t.join();
}
std::cout << "๊ฐ๊ฐ ๋ฐฐ์ด์ ํฉ์" << result[0] << "๊ณผ" << result[1] << std::endl;
std::cout << "๋ ๊ฐ ๋ฐฐ์ด์ ํฉ์" << result[0] + result[1] << std::endl;
return 0;
}
std::vector<std::thread> workers(std::vector<int>& v, std::vector<int>* result)
{
std::vector<std::thread> threads;
threads.emplace_back(accumulate_block_worker, v.data(), v.size() / 2, &((*result)[0]));
threads.emplace_back(accumulate_block_worker, v.data(), v.size() / 2, &((*result)[1]));
return threads;
}
void accumulate_block_worker(int* data, size_t count, int* result)
{
*result = std::accumulate(data, data + count, 0); //#include <numeric>
}
#include <iostream>
#include <chrono>
#include <numeric>
#include <vector>
#include <future>
int accumulate_block_worker(int*, size_t);
std::vector<std::future<int>> launch_split_workers(std::vector<int>&);
int main(void)
{
std::vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
std::vector<std::future<int>> futures = launch_split_workers(v);
int result0 = futures[0].get();
int result1 = futures[1].get();
std::cout << "๊ฐ๊ฐ ๋ฐฐ์ด์ ํฉ์ " << result0 << "๊ณผ" << result1 << std::endl;
std::cout << "๋ ๊ฐ ๋ฐฐ์ด์ ํฉ์ " << result0 + result1 << std::endl;
}
int accumulate_block_worker(int* data, size_t count)
{
return std::accumulate(data, data + count, 0); //#include <numeric>
}
std::vector<std::future<int>> launch_split_workers(std::vector<int>&v)
{
std::vector<std::future<int>> futures;
//๋น๋๊ธฐ ์ค๋ ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฒกํฐ ๊ฐ์ฒด์ ์
๋ ฅํ๋ค.
futures.emplace_back(std::async(std::launch::async, accumulate_block_worker,
v.data(), v.size() / 2));
futures.emplace_back(std::async(std::launch::async, accumulate_block_worker,
v.data()+v.size()/2, v.size() / 2));
return futures;
}
future ํด๋์ค๊ฐ ์ ๊ณตํ๋ wait()ํจ์๋ ์์ ์ ์คํ์ด ์๋ฃ๋์ด ํจ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ ์ ์๋ ์ํ๊ฐ ๋์์ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ธฐ๋ฅ์ ์ํํ๋ค. ๋ฐ๋ฉด์ get()ํจ์๋ ์ค๋ ๋๋ก ์คํ๋๋ ํจ์๊ฐ ๋ฐํํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ์ญํ ์ ์ํํ๋ค. ๋ฐ๋ผ์ ๋ง์ฝ ํจ์์ ์คํ์ด ์ข ๋ฃ๋์ง ์์๋ค๋ฉด ์ข ๋ฃ๋์ด ๋ฐํ๋ฐ์ ์ ์์ ๋ ๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค. wait()์ธ wait_for(), wait_until()ํจ์๋ ์ ๊ณตํ๋ค.
โpromise ํด๋์ค ํ ํ๋
์์ ๊ณต๊ฐ์ ์ค๋ ๋๋ณ๋ก ๋ง๋ ๋ค. ํ๋์ promise๊ฐ์ฒด๋ฅผ ํตํด future๊ฐ์ฒด๊ฐ ์์ฑ ๋์๋ค๋ฉด ๊ณต์ ํ ์์ ๊ณต๊ฐ์ด ํ๋ ์์ฑ ๋์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. async()ํจ์๊ฐ ์๋ promise๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๊ฐ๋ณ ์์ ๊ณต๊ฐ์ ํตํด ํ๋ ์ด์์ ์ค๋ ๋๋ก ๋ถํฐ ๋์ฌ์ ์์ ํ ๊ฒฐ๊ณผ๋ฅผ ์์งํ ์ ์๋ค๋ ์ด์ผ๊ธฐ๊ฐ ๋๋ค. ๋ง๋ค์ด ๋ณด์. ์ด ๋ํ ์ฝ๋ ์ฐธ์กฐ๋ ์์ํ์! C++17 ํ๋ก๊ทธ๋๋ฐ ๋์๋ฅผ ํตํด ์ฝ๋๋ฅผ ์์ฑํ์๋ค. ์ด๋ฒ์๋ ์ฃผ์์ ์ ์ดํด์ฃผ์์ผ๋ฉด ํ๋ค.
#include <iostream>
#include <future>
#include <thread>
#include <numeric>
#include <vector>
#include <functional>
void accumulate(std::vector<int>::iterator, std::vector<int>::iterator,std::promise<int>&&);
std::future<int> launch_promise(std::vector<int>::iterator, std::vector<int>::iterator);
int main(void)
{
int total = 0;
std::vector<int> numbers = { 1,2,3,4,5,6,7,8,9,10 };
//promise ๊ฐ์ฒด๊ฐ ์์
ํ ํ๊ฒฝ์ ๋ง๋ค๊ณ futrue๊ฐ์ฒด๋ฅผ ๋ฐํ๋ฐ๋๋ค.
std::future<int> s[2];
//6. promise๊ฐ์ฒด๋ก ๋ถํฐ ์ป์ future๊ฐ์ฒด๋ฅผ ํตํด ์์
๊ฒฐ๊ณผ๋ฅผ ์ป๋๋ค.
s[0] = launch_promise(numbers.begin(), numbers.begin() + 6);
s[1] = launch_promise(numbers.begin() + 6, numbers.end());
for (int i = 0; i < 2; ++i) {
int w = s[i].get();
std::cout << "promise-" << i << " : " << w << std::endl;
total += w;
}
std::cout << "ํฉ๊ณ : " << total << std::endl;
}
//3. promise๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ฌ์ฉํ๋ ํจ์๋ฅผ ๋ง๋ ๋ค.
void accumulate(std::vector<int>::iterator first, std::vector<int>::iterator last,
std::promise<int>&& accumulate_promise)
{
int sum = std::accumulate(first, last, 0);
//set_value() ํจ์๋ future๊ฐ์ฒด์ ์์
๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
//promise๊ฐ์ฒด๋ฅผ ํจ์์ ์ ๋ฌํ๋ ์ธ์๋ ๋ฐ๋์ rvalue์ฐธ์กฐ๋ฅด ์ฌ์ฉํด์ผ ํ๋ค.
//ํจ์ ๋ด๋ถ์์ ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ ๋ณต์ฌ๋ ๊ฐ์ฒด๊ฐ ์๋ ์ด๋๊ฐ์ฒด๊ฐ ๋์ด์ผ ํ๋ค.
//7. ์ค๋ ๋๋ก ์คํ๋๋ ํจ์์ ์์
๊ฒฐ๊ณผ๋ฅผ set_valueํจ์๋ฅผ ์ฌ์ฉํ์ฌ
// promise๊ฐ์ฒด๋ฅผ ํตํด future๊ฐ์ฒด์ ์ ๊ณตํ๋ค.
accumulate_promise.set_value(sum);
}
std::future<int> launch_promise(std::vector<int>::iterator first, std::vector<int>::iterator last)
{
// 1. promise๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
std::promise<int> accumulate_promise;
// 2. promise๊ฐ์ฒด๊ฐ ์ ๊ณตํ๋ get_futureํจ์๋ฅผ ์ฌ์ฉํ์ฌ futrue๊ฐ์ฒด๋ฅผ ์ป๋๋ค.
std::future<int> result = accumulate_promise.get_future();
// 4. ์ค๋ ๋๋ฅผ ์์ฑํ๊ณ ์คํ์ํจ๋ค.
std::thread work_thread(accumulate, first, last, std::move(accumulate_promise));
work_thread.detach();
return result;
}
์ต๊ทผ ์ ๋ฐ์ดํธ: 2021_03_14
๋ถ์กฑํ ๋ถ๋ถ์ด ์๋ค๋ฉด, ์ฐจํ์ ์ ๋ฐ์ดํธ ํ๊ฒ ์ต๋๋ค.
'๐จ๐ปโ๐ป programming > โฝ c, c++' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C++] ์ ๋ค๋ฆญ ์๊ณ ๋ฆฌ์ฆ ๋ชจ์ (0) | 2022.05.16 |
---|---|
[C++] std::string_view ํด๋์ค (0) | 2022.02.09 |
[C++] ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ ํ๋กํ ํ์ & ํ๊ณ (0) | 2022.02.08 |
(์ ๋ฌธ๊ฐ๋ฅผ ์ํ C++/ ๊ฐ์ 4ํ) - I/O ์ ์ถ๋ ฅ ์์ ๋ถ์ (0) | 2022.01.31 |
(c++) ์กฐ๊ฑด ๋ณ์(Conditional Variable) (0) | 2021.03.13 |
์ ํ๋ ๊ฒ ๋ณด๋ค ๋ซ๊ฒ ์ง
ํฌ์คํ ์ด ์ข์๋ค๋ฉด "์ข์์โค๏ธ" ๋๋ "๊ตฌ๋ ๐๐ป" ํด์ฃผ์ธ์!