KEMBAR78
C++ Lambda and concurrency | PPTX
Lambda Expression
& Concurrency API
김명신 부장
Principal Technical Evangelist
완전 친절한
Lambda
Expression
완전 불친절한
Concurrency API
완전 간단한
실천적 접근
Alonzo Church
[lambda-capture] { body }
[lambda-capture] (params) { body }
[lambda-capture] (params) -> ret { body }
[lambda-capture] (params) mutable exception attribute -> ret { body }
[lambda-capture] (params) mutable exception attribute -> ret { body }
int x = 10, y = 20;
[] {}; // capture 하지 않음
[x](int arg) { return x;}; // value(Copy) capture x
[=] { return x;}; // value(Copy) capture all
[&] { return y;}; // reference capture all
[&, x] { return y;}; // reference capture all except x
[=, &y] { return x;}; // value(Copy) capture all except y
[this] { return this->something;}; // this capture
[=, x] {}; // error
[&, &x] {}; // error
[=, this] {}; // error
[x, x] {}; // error
Capture default =, &를 하였더라도 body에서
사용하지 않았다면 capture는 일어나지 않음
[lambda-capture] (params) mutable exception attribute -> ret { body }
[](int &factor, int total) {
if (factor == 0) return total;
return factor;
};
[](float &factor, double total) -> double {
if (factor == 0) return total;
return factor;
};
[lambda-capture] (params) mutable exception attribute -> ret { body }
[x]() mutable { return ++x; };
[x]() throw() {
if (x == 0)
throw std::bad_exception(); // warning
};
cout << typeid([] {}).name() << endl; class <lambda_04197a50f746795ff56aab1f0f0bfa52>
int x = 10, y = 20;
[x] { return ++x; };
[x, &] { return x + y; };
[=, x] { return x; };
[]() noexcept { throw bad_exception(); };
[x]() mutable { return ++x; };
[&, x] { return x + y; };
[=] { return ++x; };
[] { throw bad_exception(); };
int x = 1;
cout << x << endl;
[x]() mutable { ++x; }();
cout << x << endl;
[&x]() { ++x; }();
cout << x << endl;
1
1
2
1
2
2
void fa(int x, function<void(void)> f) { ++x; f(); }
void fb(int x, function<void(int)> f) { ++x; f(x); }
void fc(int &x, function<void(void)> f) { ++x; f(); }
int x = 1;
fa(x, [x] { cout << x << endl; });
fb(x, [](int x) { cout << x << endl; });
fc(x, [&x] { cout << x << endl; });
struct Less
{
bool operator()(const int &left, const int &right) const
{
return left < right;
}
};
sort(begin(v), end(v), Less());
sort(begin(v), end(v), [](int x, int y) { return x < y; });
template<typename T>
class Less_than {
const T val;
public:
Less_than(const T& v) : val(v) {};
bool operator()(const T& x) const { return x < val; };
};
int num = 5;
Less_than<int> less5{ num };
auto diff = count_if(begin(v), end(v), less5);
auto diff = count_if(begin(v), end(v), [num](int value) { return value < num; });
// return lambda function
auto addtwointegers = [](int x) -> function<int(int)> {
return [=](int y) { return x + y; };
};
// lambda function as parameter
auto higherorder = [](const function<int(int)>& f, int z) {
return f(z) * 2;
};
auto answer = higherorder(addtwointegers(7), 8);
WNDCLASSEX wcex;
wcex.lpfnWndProc= [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ->
LRESULT {
switch (message) {
case WM_COMMAND:
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
char szText[256];
GetWindowTextA(hwnd, szText, 256);
cout << szText << endl;
return TRUE;
}, 0);
HANDLE hT = CreateThread(NULL, 0, [](LPVOID lpThreadParameter) -> DWORD {
for (int i = 0; i < 1000; i++) {
this_thread::sleep_for(milliseconds{ 10 });
cout << i << endl;
}
return 0;
}, NULL, 0, NULL);
sizeof(int) = ?
1=sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)
1<=sizeof(bool)<=sizeof(long)
sizeof(char)<=sizeof(wchar_t)<=sizeof(long)
sizeof(float)<=sizeof(double)<=sizeof(long double)
sizeof(N)=sizeof(signed N)=sizeof(unsigned N)
void f2(const int arg) { cout << "f2(" << arg << ")" << endl; }
void f3(const int arg, int *pResult) {
cout << "f3(" << arg << ")" << endl; *pResult = arg; }
int _tmain(int argc, _TCHAR* argv [])
{
thread t1([] { cout << "f1()" << endl; }); // lambda expression
thread t2(f2, 10); // passing argument
int result;
thread t3(f3, 10, &result); // how to get the result
t1.join();t2.join(); t3.join(); // barrier
cout << "Result = " << result << endl;
}
void f2(const int arg) { cout << "f2(" << arg << ")" << endl; }
void f3(const int arg, int *pResult) {
cout << "f3(" << arg << ")" << endl; *pResult = arg;
}
int f4(const int arg) {
cout << "f4(" << arg << ")" << endl; return arg;
}
int _tmain(int argc, _TCHAR* argv [])
{
auto t1 = async([] { cout << "f1()" << endl; }); // lambda expression
auto t2 = async(f2, 10); // passing argument
int result;
auto t3 = async(f3, 10, &result); // how to get the result
t1.get(); t2.get(); t3.get();
auto t4 = async(f4, 10); // return value
result = t4.get();
cout << "Result = " << result << endl;
}
get()
set_value()
set_exception()
int sum(int n) { return n == 1 ? 1 : n + sum(n - 1); }
....
using value_type = int;
promise<value_type> pr;
future<value_type> fu = pr.get_future();
int num = 10;
pr.set_value(sum(num));
//pr.set_exception(make_exception_ptr(exception("error")));
try {
value_type result = fu.get();
cout << result;
} catch (exception &ex) {
cout << ex.what() << endl;
}
using value_type = int;
promise<value_type> pr;
future<value_type> fu = pr.get_future();
int num = 10;
thread t{ [&,num] {
pr.set_value(sum(num));
//pr.set_exception(make_exception_ptr(exception("error")));
}};
try {
value_type result = fu.get();
cout << result;
} catch (exception &ex) {
cout << ex.what() << endl;
}
t.join();
get()
set_value(x)
set_exception(x)
return x;
throw x;
try {
pr.set_value(tsk(args));
} catch (...) {pr.set_exception(current_exception()); }
using value_type = int;
packaged_task<value_type(int)> pt{ sum };
future<value_type> fu = pt.get_future();
int num = 10;
pt(num);
try {
value_type result = fu.get();
cout << result;
} catch (exception &ex) {
cout << ex.what() << endl;
}
using value_type = int;
packaged_task<value_type(int)> pt{ sum };
future<value_type> fu = pt.get_future();
int num = 10;
thread t{ move(pt), 10 };
try {
value_type result = fu.get();
cout << result;
} catch (exception &ex) {
cout << ex.what() << endl;
}
t.join();
void producer()
{
int x = 1;
while (x)
{
packaged_task<int()> pt{ bind(sum, x++) };
{
unique_lock<mutex> ul(mtx);
q.push_back(move(pt));
}
cond.notify_one();
this_thread::sleep_for(milliseconds{ 100 });
}
}
void consumer()
{
while (true)
{
packaged_task<int(void)> pt;
{
unique_lock<mutex> ul(mtx);
cond.wait(ul, [] {return !q.empty(); });
pt = move(q.front());
}
pt();
cout << pt.get_future().get() << endl;
q.pop_front();
}
}
int sum(int n) { return n == 1 ? 1 : n + sum(n - 1); }
deque<packaged_task<int()> > q;
mutex mtx;
condition_variable cond;
using value_type = int;
future<value_type> fu = async(sum, 10);
try {
value_type result = fu.get();
cout << result;
} catch (exception &ex) {
cout << ex.what() << endl;
}
C++ Lambda and concurrency
C++ Lambda and concurrency
C++ Lambda and concurrency
C++ Lambda and concurrency

C++ Lambda and concurrency

  • 1.
    Lambda Expression & ConcurrencyAPI 김명신 부장 Principal Technical Evangelist
  • 2.
  • 5.
  • 6.
    [lambda-capture] { body} [lambda-capture] (params) { body } [lambda-capture] (params) -> ret { body } [lambda-capture] (params) mutable exception attribute -> ret { body }
  • 7.
    [lambda-capture] (params) mutableexception attribute -> ret { body } int x = 10, y = 20; [] {}; // capture 하지 않음 [x](int arg) { return x;}; // value(Copy) capture x [=] { return x;}; // value(Copy) capture all [&] { return y;}; // reference capture all [&, x] { return y;}; // reference capture all except x [=, &y] { return x;}; // value(Copy) capture all except y [this] { return this->something;}; // this capture [=, x] {}; // error [&, &x] {}; // error [=, this] {}; // error [x, x] {}; // error Capture default =, &를 하였더라도 body에서 사용하지 않았다면 capture는 일어나지 않음
  • 8.
    [lambda-capture] (params) mutableexception attribute -> ret { body } [](int &factor, int total) { if (factor == 0) return total; return factor; }; [](float &factor, double total) -> double { if (factor == 0) return total; return factor; };
  • 9.
    [lambda-capture] (params) mutableexception attribute -> ret { body } [x]() mutable { return ++x; }; [x]() throw() { if (x == 0) throw std::bad_exception(); // warning };
  • 11.
    cout << typeid([]{}).name() << endl; class <lambda_04197a50f746795ff56aab1f0f0bfa52>
  • 13.
    int x =10, y = 20; [x] { return ++x; }; [x, &] { return x + y; }; [=, x] { return x; }; []() noexcept { throw bad_exception(); }; [x]() mutable { return ++x; }; [&, x] { return x + y; }; [=] { return ++x; }; [] { throw bad_exception(); };
  • 14.
    int x =1; cout << x << endl; [x]() mutable { ++x; }(); cout << x << endl; [&x]() { ++x; }(); cout << x << endl; 1 1 2
  • 15.
    1 2 2 void fa(int x,function<void(void)> f) { ++x; f(); } void fb(int x, function<void(int)> f) { ++x; f(x); } void fc(int &x, function<void(void)> f) { ++x; f(); } int x = 1; fa(x, [x] { cout << x << endl; }); fb(x, [](int x) { cout << x << endl; }); fc(x, [&x] { cout << x << endl; });
  • 16.
    struct Less { bool operator()(constint &left, const int &right) const { return left < right; } }; sort(begin(v), end(v), Less()); sort(begin(v), end(v), [](int x, int y) { return x < y; });
  • 17.
    template<typename T> class Less_than{ const T val; public: Less_than(const T& v) : val(v) {}; bool operator()(const T& x) const { return x < val; }; }; int num = 5; Less_than<int> less5{ num }; auto diff = count_if(begin(v), end(v), less5); auto diff = count_if(begin(v), end(v), [num](int value) { return value < num; });
  • 18.
    // return lambdafunction auto addtwointegers = [](int x) -> function<int(int)> { return [=](int y) { return x + y; }; }; // lambda function as parameter auto higherorder = [](const function<int(int)>& f, int z) { return f(z) * 2; }; auto answer = higherorder(addtwointegers(7), 8);
  • 19.
    WNDCLASSEX wcex; wcex.lpfnWndProc= [](HWNDhWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT { switch (message) { case WM_COMMAND: EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL { char szText[256]; GetWindowTextA(hwnd, szText, 256); cout << szText << endl; return TRUE; }, 0);
  • 20.
    HANDLE hT =CreateThread(NULL, 0, [](LPVOID lpThreadParameter) -> DWORD { for (int i = 0; i < 1000; i++) { this_thread::sleep_for(milliseconds{ 10 }); cout << i << endl; } return 0; }, NULL, 0, NULL);
  • 28.
  • 29.
  • 36.
    void f2(const intarg) { cout << "f2(" << arg << ")" << endl; } void f3(const int arg, int *pResult) { cout << "f3(" << arg << ")" << endl; *pResult = arg; } int _tmain(int argc, _TCHAR* argv []) { thread t1([] { cout << "f1()" << endl; }); // lambda expression thread t2(f2, 10); // passing argument int result; thread t3(f3, 10, &result); // how to get the result t1.join();t2.join(); t3.join(); // barrier cout << "Result = " << result << endl; }
  • 37.
    void f2(const intarg) { cout << "f2(" << arg << ")" << endl; } void f3(const int arg, int *pResult) { cout << "f3(" << arg << ")" << endl; *pResult = arg; } int f4(const int arg) { cout << "f4(" << arg << ")" << endl; return arg; } int _tmain(int argc, _TCHAR* argv []) { auto t1 = async([] { cout << "f1()" << endl; }); // lambda expression auto t2 = async(f2, 10); // passing argument int result; auto t3 = async(f3, 10, &result); // how to get the result t1.get(); t2.get(); t3.get(); auto t4 = async(f4, 10); // return value result = t4.get(); cout << "Result = " << result << endl; }
  • 39.
  • 40.
    int sum(int n){ return n == 1 ? 1 : n + sum(n - 1); } .... using value_type = int; promise<value_type> pr; future<value_type> fu = pr.get_future(); int num = 10; pr.set_value(sum(num)); //pr.set_exception(make_exception_ptr(exception("error"))); try { value_type result = fu.get(); cout << result; } catch (exception &ex) { cout << ex.what() << endl; }
  • 41.
    using value_type =int; promise<value_type> pr; future<value_type> fu = pr.get_future(); int num = 10; thread t{ [&,num] { pr.set_value(sum(num)); //pr.set_exception(make_exception_ptr(exception("error"))); }}; try { value_type result = fu.get(); cout << result; } catch (exception &ex) { cout << ex.what() << endl; } t.join();
  • 43.
    get() set_value(x) set_exception(x) return x; throw x; try{ pr.set_value(tsk(args)); } catch (...) {pr.set_exception(current_exception()); }
  • 44.
    using value_type =int; packaged_task<value_type(int)> pt{ sum }; future<value_type> fu = pt.get_future(); int num = 10; pt(num); try { value_type result = fu.get(); cout << result; } catch (exception &ex) { cout << ex.what() << endl; }
  • 45.
    using value_type =int; packaged_task<value_type(int)> pt{ sum }; future<value_type> fu = pt.get_future(); int num = 10; thread t{ move(pt), 10 }; try { value_type result = fu.get(); cout << result; } catch (exception &ex) { cout << ex.what() << endl; } t.join();
  • 46.
    void producer() { int x= 1; while (x) { packaged_task<int()> pt{ bind(sum, x++) }; { unique_lock<mutex> ul(mtx); q.push_back(move(pt)); } cond.notify_one(); this_thread::sleep_for(milliseconds{ 100 }); } } void consumer() { while (true) { packaged_task<int(void)> pt; { unique_lock<mutex> ul(mtx); cond.wait(ul, [] {return !q.empty(); }); pt = move(q.front()); } pt(); cout << pt.get_future().get() << endl; q.pop_front(); } } int sum(int n) { return n == 1 ? 1 : n + sum(n - 1); } deque<packaged_task<int()> > q; mutex mtx; condition_variable cond;
  • 47.
    using value_type =int; future<value_type> fu = async(sum, 10); try { value_type result = fu.get(); cout << result; } catch (exception &ex) { cout << ex.what() << endl; }