SlideShare a Scribd company logo
C++ Concurrency in Action Study
C++ Korea
Chapter	09 Advanced	thread	management
9.2	Interrupting	threads
C++ Korea
C++ Concurrency in Action
Study C++ Korea 박 동하 (luncliff@gmail.com)
C++ Korea 윤석준 (seokjoon.yun@gmail.com)
C++ Concurrency in Action Study
C++ Korea
Interrupting Thread
• long-running	thread를 정지시킬 때
• 동작중인 thread가 아닌 다른 thread에서 작업을 중지시키고 싶을 때
• 특히 사용자가 명시적으로 [작업 취소]를 누른 경우
• GUI	(특히 MFC)에서는 Signal	(Message)로 처리
• C++11에서는 interrupting	thread를 제공해주지 않지만,	쉽게 구현이 가능함
• 기존 thread에 interrupt거는 함수와 interrupt되는 함수 구현이면 끝!
interrupt( ) interrupt_point( )
2
C++ Concurrency in Action Study
C++ Korea
Basic Implementation
of interruptible_thread
Simple하게 while-loop	안에서interrupt	check
C++ Concurrency in Action Study
C++ Korea
interruptible_thread
4
class interruptible_thread
{
std::thread internal_thread;
interrupt_flag* flag;
public:
template<typename FunctionType>
interruptible_thread(FunctionType f)
{
std::promise<interrupt_flag*> p;
internal_thread = std::thread([f, &p] {
p.set_value(&this_thread_interrupt_flag);
f();
});
flag = p.get_future().get();
}
void interrupt()
{
if (flag)
flag->set();
}
void join() { internal_thread.join(); }
void detach() { internal_thread.detach(); }
bool joinable() const { return internal_thread.joinable(); }
};
std::thread	기능
interrupt	거는 기능
생성자 :	함수 실행
C++ Concurrency in Action Study
C++ Korea
interrupt_flag
5
class interrupt_flag
{
std::atomic<bool> flag;
public:
void set()
{
flag.store(true, std::memory_order_relaxed);
}
bool is_set() const
{
return flag.load(std::memory_order_relaxed);
}
};
thread_local interrupt_flag this_thread_interrupt_flag;
void interruption_point()
{
if (this_thread_interrupt_flag.is_set())
throw thread_interrupted();
}
interrupt	거는 기능
각 thread별로 flag를 가짐
interrupt	flag
C++ Concurrency in Action Study
C++ Korea6
Basic Implementation
of interruptible_thread
DEMO !!!
C++ Concurrency in Action Study
C++ Korea
DEMO 결과는 ???
7
• 잘 동작함
• 별 문제 없어 보임
• 근데 왜 ???	작가는 ???
• while-loop에서 interrupt를blocking으로 기다리는 게마음에안 드는듯;;;
• 그래서 ?
• std::condition_variable을 이용하여 interruptible_wait()를 구현
• 추가로 std::mutex와 std::lock_guard<>도 같이 사용을… ;;;
• 하지만program	구조상while-loop를 사용하는 경우는이예제가최고의 solution이지 않을까라는 의견을 살포시조심스럽고 소심하게 제시해봄
C++ Concurrency in Action Study
C++ Korea
A Broken version of
interruptible_wait for
std::condition_variable
std::condition_variable::wait()로 대기
but,	깨우는데 쌩까고계속잘 수있음 ;;;
C++ Concurrency in Action Study
C++ Korea
interruptible_wait (추가)
9
if	set	then
throw	exception
void interruptible_wait(std::condition_variable& cv,
std::unique_lock<std::mutex>& lk)
{
interruption_point();
this_thread_interrupt_flag.set_condition_variable(cv);
cv.wait(lk);
this_thread_interrupt_flag.clear_condition_variable();
interruption_point();
}
throw	exception
C++ Concurrency in Action Study
C++ Korea
interrupt_flag (수정)
std::condition_variable*	 추가
보호할 목적의 std::mutex 추가
class interrupt_flag
{
std::atomic<bool> flag;
std::condition_variable* thread_cond;
std::mutex set_clear_mutex;
public:
interrupt_flag() : thread_cond(0) {}
void set()
{
flag.store(true, std::memory_order_relaxed);
std::lock_guard<std::mutex> lk(set_clear_mutex);
if (thread_cond)
thread_cond->notify_all();
}
bool is_set() const
{
return flag.load(std::memory_order_relaxed);
}
void set_condition_variable(std::condition_variable& cv)
{
std::lock_guard<std::mutex> lk(set_clear_mutex);
thread_cond = &cv;
}
void clear_condition_variable()
{
std::lock_guard<std::mutex> lk(set_clear_mutex);
thread_cond = 0;
}
};
set()	에 std::condition_variable::notify_all(	 )	추가
std::condition_variable이 설정되지 않아도 정상동작
std::condition_variable set()	,	clear()	함수 추가
C++ Concurrency in Action Study
C++ Korea
A Broken version of
interruptible_wait for
std::condition_variable
DEMO !!!
C++ Concurrency in Action Study
C++ Korea
DEMO 결과는 ???
12
• 잘 동작함
• 별 문제 없어 보임
• 앞서 본 while-loop	 형식도 여기서 잘 동작함
• 근데 ????
void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk)
{
interruption_point();
this_thread_interrupt_flag.set_condition_variable(cv);
cv.wait(lk);
this_thread_interrupt_flag.clear_condition_variable();
interruption_point();
}
이 사이에 interrupt가 발생한 경우 ???
C++ Concurrency in Action Study
C++ Korea
A Broken version of
interruptible_wait for
std::condition_variable
DEMO !!! #2
C++ Concurrency in Action Study
C++ Korea
DEMO 결과는 ???
14
• interrupt	씹혔음 ;;;;
• 다시 보내니깐 정상적으로 interrupt	됨
• 그럼 대안은 ????
• 그 사이를 다른 std::mutex로 보호 ?
• 서로의 수명을 모르는 thread	들끼리 mutex 참조를 통과 -> 위험함
• wait()	대신 wait_for()를 사용하여 대기 시간의 제한을 둠
• spurious	wake	(가짜 깸)이 자주 일어나겠지만 해결 됨
C++ Concurrency in Action Study
C++ Korea
Using timeout in
interruptible_wait for
std::condition_variable
깨우는거쌩까지는 않는데…
while-loop	안에서wait_for(	)로 check
C++ Concurrency in Action Study
C++ Korea
clear_cv_on_destruct (추가)
16
std::condition_variable의clear()를 RAII로 관리
struct clear_cv_on_destruct
{
~clear_cv_on_destruct()
{
this_thread_interrupt_flag.clear_condition_variable();
}
};
C++ Concurrency in Action Study
C++ Korea
interruptible_wait (수정)
17
void interruptible_wait(std::condition_variable& cv,
std::unique_lock<std::mutex>& lk)
{
interruption_point();
this_thread_interrupt_flag.set_condition_variable(cv);
clear_cv_on_destruct guard;
interruption_point();
cv.wait_for(lk, std::chrono::milliseconds(1));
interruption_point();
}
when	cv	set	and
throw	exception
without	cv	clear,
then
cv	clear	automatically
C++ Concurrency in Action Study
C++ Korea
interruptible_wait using predicate (추가)
18
template<typename Predicate>
void interruptible_wait(std::condition_variable& cv,
std::unique_lock<std::mutex>& lk,
Predicate pred)
{
interruption_point();
this_thread_interrupt_flag.set_condition_variable(cv);
interrupt_flag::clear_cv_on_destruct guard;
while (!thie_thread_interrupt_flag.is_set() && !pred())
{
cv.wait_for(lk, std::chrono::milliseconds(1));
}
interruption_point();
}
C++ Concurrency in Action Study
C++ Korea
Using timeout in
interruptible_wait for
std::condition_variable
DEMO !!!
C++ Concurrency in Action Study
C++ Korea
DEMO 결과는 ???
20
• 잘 동작함
• 무슨 수를 써도 무조건 잘 동작함
• 근데 std::condition_variable 말고
std::condition_variable_any를쓸려면 ???
(그냥std::unique_lock<std::mutex>만 쓰면될껄….	또뭘더쓸려고…	참…)
C++ Concurrency in Action Study
C++ Korea
interruptible_wait for
std::condition_variable_any
std::condition_variable_any를 작가님이굳이쓰시겠다는데 머…
다시while-loop	없이 wait(	)로 대기
C++ Concurrency in Action Study
C++ Korea
interrupt_flag에 std::condition_variable_any 추가
22
class interrupt_flag
{
std::atomic<bool> flag;
std::condition_variable* thread_cond;
std::condition_variable_any* thread_cond_any;
std::mutex set_clear_mutex;
public:
interrupt_flag()
: thread_cond(0)
, thread_cond_any(0) {}
void set()
{
flag.store(true, std::memory_order_relaxed);
std::lock_guard<std::mutex> lk(set_clear_mutex);
if (thread_cond)
thread_cond->notify_all();
else if (thread_cond_any)
thread_cond_any->notify_all();
}
std::condition_variable_any*	 추가
std::condition_variable_any의 notify_all()	 추가
C++ Concurrency in Action Study
C++ Korea
interrupt_flag에 wait( ) (추가)
23
template<typename Lockable>
void interrupt_flag::wait(std::condition_variable_any& cv,
Lockable& lk)
{
struct custom_lock { … };
custom_lock cl(this, cv, lk);
interruption_point();
cv.wait(cl);
interruption_point();
}
struct custom_lock
{
interrupt_flag* self;
Lockable& lk;
custom_lock(interrupt_flag* self_,
std::condition_variable_any& cond,
Lockable& lk_)
: self(self_)
, lk(lk_)
{
self->set_clear_mutex.lock();
self->thread_cond_any = &cond;
}
void unlock()
{
lk.unlock();
self->set_clear_mutex.unlock();
}
void lock()
{
std::lock(self->set_clear_mutex, lk);
}
~custom_lock()
{
self->thread_cond_any = 0;
self->set_clear_mutex.unlock();
}
};
lock
unlock
exception이 발생하여도 무조건 unlock
template<typename Lockable>
void interruptible_wait(std::condition_variable_any& cv,
Lockable& lk)
{
this_thread_interrupt_flag.wait(cv, lk);
}
C++ Concurrency in Action Study
C++ Korea
interruptible_wait for
std::condition_variable_any
DEMO !!!
C++ Concurrency in Action Study
C++ Korea
DEMO 결과는 ???
25
• 잘 동작함
• 뚤어보려 애썼는데…	안뚤림 ;;;
• 작가님이 한가지만 더 살펴보자는데…
std::future 같이 다른 blocking	call에 interrupt를 주려면 ???
C++ Concurrency in Action Study
C++ Korea
interrupting
other blocking calls
C++ Concurrency in Action Study
C++ Korea
interruptible_wait( ) using std::future
27
interrupt가 걸려도 빠져나가고
template<typename T>
void interruptible_wait(std::future<T>& uf)
{
while (!this_thread_interrupt_flag.is_set())
{
if (uf.wait_for(lk, std::future_status::ready
== std::chrono::milliseconds(1)))
break;
}
}
작업이 끝나도 빠져나가고
주기적으로 check
C++ Concurrency in Action Study
C++ Korea
interrupting
other blocking calls
DEMO ???
Pass !!!
고마보자.	많이봤다.	아이가;;;
C++ Concurrency in Action Study
C++ Korea
Handling interrupt
그동안 DEMO에서많이봤는데…
맹그거임.
C++ Concurrency in Action Study
C++ Korea
Handling interrupt
30
딱히 설명이 필요할지…
try
{
do_something();
}
catch (thread_interrupted&)
{
handle_interrupt();
}
C++ Concurrency in Action Study
C++ Korea
Handling interrupt
31
딱히 설명이 필요할지…
try
{
do_something();
}
catch (thread_interrupted&)
{
handle_interrupt();
}
- 그런데,	이렇게 외부에서 exception을 처리 하는 경우,	만약 실수로 처리를 안하게 되면 ?
std::terminate()가 호출되어 program이 종료 될 수도 있다.
- 왠만하면 thread	내부에서 exception을 처리해 주는게 안전하다.
C++ Concurrency in Action Study
C++ Korea
Handling interrupt in internal_thread constructor
32
아에 internal_thread 생성시
함수 실행 부분에서 exception 처리를 했다.
template<typename FunctionType>
interruptible_thread(FunctionType f)
{
std::promise<interrupt_flag*> p;
internal_thread = std::thread([f, &p] {
p.set_value(&this_thread_interrupt_flag);
try
{
f();
}
catch (thread_interrupted const&)
{
handle_interrupt();
}
});
flag = p.get_future().get();
}
C++ Concurrency in Action Study
C++ Korea
Summary
33
• 여러가지 방법으로 thread를 interrupt하는 방법을 살펴 봄.
• while-loop	안에서 interruption_point(	)	체크
• std::condition_variable,	std::condition_variable_any를 이용
• 다른 blocking	방법에 대한 예제 (std::future)
C++ Concurrency in Action Study
C++ Korea
Q & A

More Related Content

PDF
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
PPTX
Startup JavaScript 3 - 조건문, 반복문, 예외처리
PPTX
포트폴리오에서 사용한 모던 C++
PPTX
[devil's camp] - 알고리즘 대회와 STL (박인서)
PDF
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
PDF
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
PDF
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
PDF
[C++ Korea 2nd Seminar] C++17 Key Features Summary
Effective Modern C++ MVA item 18 Use std::unique_ptr for exclusive-ownership ...
Startup JavaScript 3 - 조건문, 반복문, 예외처리
포트폴리오에서 사용한 모던 C++
[devil's camp] - 알고리즘 대회와 STL (박인서)
[C++ Korea] Effective Modern C++ MVA item 9 Prefer alias declarations to type...
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[C++ Korea] Effective Modern C++ MVA item 8 Prefer nullptr to 0 and null +윤석준
[C++ Korea 2nd Seminar] C++17 Key Features Summary

What's hot (20)

PPTX
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
PDF
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
PDF
프로그래밍 대회: C++11 이야기
PPTX
Startup JavaScript 6 - 함수, 스코프, 클로저
PDF
2.Startup JavaScript - 연산자
PDF
2013 C++ Study For Students #1
PDF
C++17 Key Features Summary - Ver 2
PPTX
프론트엔드스터디 E05 js closure oop
PPTX
Javascript 함수(function) 개념, 호출패턴, this, prototype, scope
PDF
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
PPTX
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
PPTX
[C++ korea] effective modern c++ study item8~10 정은식
PDF
[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...
PPTX
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
PPTX
프론트엔드스터디 E04 js function
PPTX
Effective c++(chapter 5,6)
PDF
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
PPTX
[KGC 2011]Boost 라이브러리와 C++11
PDF
스위프트 성능 이해하기
PPTX
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
프로그래밍 대회: C++11 이야기
Startup JavaScript 6 - 함수, 스코프, 클로저
2.Startup JavaScript - 연산자
2013 C++ Study For Students #1
C++17 Key Features Summary - Ver 2
프론트엔드스터디 E05 js closure oop
Javascript 함수(function) 개념, 호출패턴, this, prototype, scope
[C++ korea] effective modern c++ study item 7 distinguish between () and {} w...
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
[C++ korea] effective modern c++ study item8~10 정은식
[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
프론트엔드스터디 E04 js function
Effective c++(chapter 5,6)
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[KGC 2011]Boost 라이브러리와 C++11
스위프트 성능 이해하기
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Ad

Viewers also liked (20)

PDF
Concurrency in action - chapter 5
PPTX
Pro typescript.ch07.Exception, Memory, Performance
PDF
Concurrency in action - chapter 7
PPT
Dieznuevascompetenciasparaensear 110405165528-phpapp01
DOCX
Autoformas
PPTX
Final Presentation MNFPC
PPT
La energía
PPTX
Imagenes animación
PDF
PPTX
Telemarketing services: Make Your Marketing Campaign More Productive
PPTX
Norma Hurtado
PDF
Badania satysfakcji klienta z platformą Webankieta
DOCX
CV -linked in
PPTX
Film referencing a2
PPTX
Post card analysis
PPT
Integrating spirituality 1.0
PPT
Biblical worldview
PDF
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
PDF
CV_ Ngo Xuan Cam Thu_UPDATED 160301
DOCX
Resumeforthestate
Concurrency in action - chapter 5
Pro typescript.ch07.Exception, Memory, Performance
Concurrency in action - chapter 7
Dieznuevascompetenciasparaensear 110405165528-phpapp01
Autoformas
Final Presentation MNFPC
La energía
Imagenes animación
Telemarketing services: Make Your Marketing Campaign More Productive
Norma Hurtado
Badania satysfakcji klienta z platformą Webankieta
CV -linked in
Film referencing a2
Post card analysis
Integrating spirituality 1.0
Biblical worldview
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
CV_ Ngo Xuan Cam Thu_UPDATED 160301
Resumeforthestate
Ad

Similar to C++ Concurrency in Action 9-2 Interrupting threads (20)

PDF
[143] Modern C++ 무조건 써야 해?
PPTX
Smc–state machinecompiler
PPTX
Design Pattern - Multithread Ch10
PPTX
불어오는 변화의 바람, From c++98 to c++11, 14
PDF
Basic git-commands
PDF
Effective c++ chapter1 2_dcshin
PDF
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
PPTX
Android+init+process
PDF
[1B4]안드로이드 동시성_프로그래밍
PPTX
Clean code
PDF
Lambda 란 무엇인가
PDF
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
PDF
MutiCore 19-20
PPTX
Multi-thread : producer - consumer
PPTX
javascript02
PPTX
C++ 프로젝트에 단위 테스트 도입하기
PPTX
파이썬 스터디 15장
PPT
카사 공개세미나1회 W.E.L.C.
PPTX
About Visual C++ 10
PDF
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
[143] Modern C++ 무조건 써야 해?
Smc–state machinecompiler
Design Pattern - Multithread Ch10
불어오는 변화의 바람, From c++98 to c++11, 14
Basic git-commands
Effective c++ chapter1 2_dcshin
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
Android+init+process
[1B4]안드로이드 동시성_프로그래밍
Clean code
Lambda 란 무엇인가
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
MutiCore 19-20
Multi-thread : producer - consumer
javascript02
C++ 프로젝트에 단위 테스트 도입하기
파이썬 스터디 15장
카사 공개세미나1회 W.E.L.C.
About Visual C++ 10
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?

More from Seok-joon Yun (20)

PDF
Retrospective.2020 03
PDF
Sprint & Jira
PPTX
Eks.introduce.v2
PDF
Eks.introduce
PDF
AWS DEV DAY SEOUL 2017 Buliding Serverless Web App - 직방 Image Converter
PDF
아파트 시세,어쩌다 머신러닝까지
PPTX
Doing math with python.ch07
PPTX
Doing math with python.ch06
PPTX
Doing math with python.ch05
PPTX
Doing math with python.ch04
PPTX
Doing math with python.ch03
PPTX
Doing mathwithpython.ch02
PPTX
Doing math with python.ch01
PPTX
Pro typescript.ch03.Object Orientation in TypeScript
PDF
Welcome to Modern C++
PDF
[2015-07-20-윤석준] Oracle 성능 관리 2
PDF
[2015-07-10-윤석준] Oracle 성능 관리 & v$sysstat
PDF
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
PDF
오렌지6.0 교육자료
PDF
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
Retrospective.2020 03
Sprint & Jira
Eks.introduce.v2
Eks.introduce
AWS DEV DAY SEOUL 2017 Buliding Serverless Web App - 직방 Image Converter
아파트 시세,어쩌다 머신러닝까지
Doing math with python.ch07
Doing math with python.ch06
Doing math with python.ch05
Doing math with python.ch04
Doing math with python.ch03
Doing mathwithpython.ch02
Doing math with python.ch01
Pro typescript.ch03.Object Orientation in TypeScript
Welcome to Modern C++
[2015-07-20-윤석준] Oracle 성능 관리 2
[2015-07-10-윤석준] Oracle 성능 관리 & v$sysstat
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
오렌지6.0 교육자료
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3

C++ Concurrency in Action 9-2 Interrupting threads

  • 1. C++ Concurrency in Action Study C++ Korea Chapter 09 Advanced thread management 9.2 Interrupting threads C++ Korea C++ Concurrency in Action Study C++ Korea 박 동하 (luncliff@gmail.com) C++ Korea 윤석준 (seokjoon.yun@gmail.com)
  • 2. C++ Concurrency in Action Study C++ Korea Interrupting Thread • long-running thread를 정지시킬 때 • 동작중인 thread가 아닌 다른 thread에서 작업을 중지시키고 싶을 때 • 특히 사용자가 명시적으로 [작업 취소]를 누른 경우 • GUI (특히 MFC)에서는 Signal (Message)로 처리 • C++11에서는 interrupting thread를 제공해주지 않지만, 쉽게 구현이 가능함 • 기존 thread에 interrupt거는 함수와 interrupt되는 함수 구현이면 끝! interrupt( ) interrupt_point( ) 2
  • 3. C++ Concurrency in Action Study C++ Korea Basic Implementation of interruptible_thread Simple하게 while-loop 안에서interrupt check
  • 4. C++ Concurrency in Action Study C++ Korea interruptible_thread 4 class interruptible_thread { std::thread internal_thread; interrupt_flag* flag; public: template<typename FunctionType> interruptible_thread(FunctionType f) { std::promise<interrupt_flag*> p; internal_thread = std::thread([f, &p] { p.set_value(&this_thread_interrupt_flag); f(); }); flag = p.get_future().get(); } void interrupt() { if (flag) flag->set(); } void join() { internal_thread.join(); } void detach() { internal_thread.detach(); } bool joinable() const { return internal_thread.joinable(); } }; std::thread 기능 interrupt 거는 기능 생성자 : 함수 실행
  • 5. C++ Concurrency in Action Study C++ Korea interrupt_flag 5 class interrupt_flag { std::atomic<bool> flag; public: void set() { flag.store(true, std::memory_order_relaxed); } bool is_set() const { return flag.load(std::memory_order_relaxed); } }; thread_local interrupt_flag this_thread_interrupt_flag; void interruption_point() { if (this_thread_interrupt_flag.is_set()) throw thread_interrupted(); } interrupt 거는 기능 각 thread별로 flag를 가짐 interrupt flag
  • 6. C++ Concurrency in Action Study C++ Korea6 Basic Implementation of interruptible_thread DEMO !!!
  • 7. C++ Concurrency in Action Study C++ Korea DEMO 결과는 ??? 7 • 잘 동작함 • 별 문제 없어 보임 • 근데 왜 ??? 작가는 ??? • while-loop에서 interrupt를blocking으로 기다리는 게마음에안 드는듯;;; • 그래서 ? • std::condition_variable을 이용하여 interruptible_wait()를 구현 • 추가로 std::mutex와 std::lock_guard<>도 같이 사용을… ;;; • 하지만program 구조상while-loop를 사용하는 경우는이예제가최고의 solution이지 않을까라는 의견을 살포시조심스럽고 소심하게 제시해봄
  • 8. C++ Concurrency in Action Study C++ Korea A Broken version of interruptible_wait for std::condition_variable std::condition_variable::wait()로 대기 but, 깨우는데 쌩까고계속잘 수있음 ;;;
  • 9. C++ Concurrency in Action Study C++ Korea interruptible_wait (추가) 9 if set then throw exception void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); cv.wait(lk); this_thread_interrupt_flag.clear_condition_variable(); interruption_point(); } throw exception
  • 10. C++ Concurrency in Action Study C++ Korea interrupt_flag (수정) std::condition_variable* 추가 보호할 목적의 std::mutex 추가 class interrupt_flag { std::atomic<bool> flag; std::condition_variable* thread_cond; std::mutex set_clear_mutex; public: interrupt_flag() : thread_cond(0) {} void set() { flag.store(true, std::memory_order_relaxed); std::lock_guard<std::mutex> lk(set_clear_mutex); if (thread_cond) thread_cond->notify_all(); } bool is_set() const { return flag.load(std::memory_order_relaxed); } void set_condition_variable(std::condition_variable& cv) { std::lock_guard<std::mutex> lk(set_clear_mutex); thread_cond = &cv; } void clear_condition_variable() { std::lock_guard<std::mutex> lk(set_clear_mutex); thread_cond = 0; } }; set() 에 std::condition_variable::notify_all( ) 추가 std::condition_variable이 설정되지 않아도 정상동작 std::condition_variable set() , clear() 함수 추가
  • 11. C++ Concurrency in Action Study C++ Korea A Broken version of interruptible_wait for std::condition_variable DEMO !!!
  • 12. C++ Concurrency in Action Study C++ Korea DEMO 결과는 ??? 12 • 잘 동작함 • 별 문제 없어 보임 • 앞서 본 while-loop 형식도 여기서 잘 동작함 • 근데 ???? void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); cv.wait(lk); this_thread_interrupt_flag.clear_condition_variable(); interruption_point(); } 이 사이에 interrupt가 발생한 경우 ???
  • 13. C++ Concurrency in Action Study C++ Korea A Broken version of interruptible_wait for std::condition_variable DEMO !!! #2
  • 14. C++ Concurrency in Action Study C++ Korea DEMO 결과는 ??? 14 • interrupt 씹혔음 ;;;; • 다시 보내니깐 정상적으로 interrupt 됨 • 그럼 대안은 ???? • 그 사이를 다른 std::mutex로 보호 ? • 서로의 수명을 모르는 thread 들끼리 mutex 참조를 통과 -> 위험함 • wait() 대신 wait_for()를 사용하여 대기 시간의 제한을 둠 • spurious wake (가짜 깸)이 자주 일어나겠지만 해결 됨
  • 15. C++ Concurrency in Action Study C++ Korea Using timeout in interruptible_wait for std::condition_variable 깨우는거쌩까지는 않는데… while-loop 안에서wait_for( )로 check
  • 16. C++ Concurrency in Action Study C++ Korea clear_cv_on_destruct (추가) 16 std::condition_variable의clear()를 RAII로 관리 struct clear_cv_on_destruct { ~clear_cv_on_destruct() { this_thread_interrupt_flag.clear_condition_variable(); } };
  • 17. C++ Concurrency in Action Study C++ Korea interruptible_wait (수정) 17 void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); clear_cv_on_destruct guard; interruption_point(); cv.wait_for(lk, std::chrono::milliseconds(1)); interruption_point(); } when cv set and throw exception without cv clear, then cv clear automatically
  • 18. C++ Concurrency in Action Study C++ Korea interruptible_wait using predicate (추가) 18 template<typename Predicate> void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk, Predicate pred) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); interrupt_flag::clear_cv_on_destruct guard; while (!thie_thread_interrupt_flag.is_set() && !pred()) { cv.wait_for(lk, std::chrono::milliseconds(1)); } interruption_point(); }
  • 19. C++ Concurrency in Action Study C++ Korea Using timeout in interruptible_wait for std::condition_variable DEMO !!!
  • 20. C++ Concurrency in Action Study C++ Korea DEMO 결과는 ??? 20 • 잘 동작함 • 무슨 수를 써도 무조건 잘 동작함 • 근데 std::condition_variable 말고 std::condition_variable_any를쓸려면 ??? (그냥std::unique_lock<std::mutex>만 쓰면될껄…. 또뭘더쓸려고… 참…)
  • 21. C++ Concurrency in Action Study C++ Korea interruptible_wait for std::condition_variable_any std::condition_variable_any를 작가님이굳이쓰시겠다는데 머… 다시while-loop 없이 wait( )로 대기
  • 22. C++ Concurrency in Action Study C++ Korea interrupt_flag에 std::condition_variable_any 추가 22 class interrupt_flag { std::atomic<bool> flag; std::condition_variable* thread_cond; std::condition_variable_any* thread_cond_any; std::mutex set_clear_mutex; public: interrupt_flag() : thread_cond(0) , thread_cond_any(0) {} void set() { flag.store(true, std::memory_order_relaxed); std::lock_guard<std::mutex> lk(set_clear_mutex); if (thread_cond) thread_cond->notify_all(); else if (thread_cond_any) thread_cond_any->notify_all(); } std::condition_variable_any* 추가 std::condition_variable_any의 notify_all() 추가
  • 23. C++ Concurrency in Action Study C++ Korea interrupt_flag에 wait( ) (추가) 23 template<typename Lockable> void interrupt_flag::wait(std::condition_variable_any& cv, Lockable& lk) { struct custom_lock { … }; custom_lock cl(this, cv, lk); interruption_point(); cv.wait(cl); interruption_point(); } struct custom_lock { interrupt_flag* self; Lockable& lk; custom_lock(interrupt_flag* self_, std::condition_variable_any& cond, Lockable& lk_) : self(self_) , lk(lk_) { self->set_clear_mutex.lock(); self->thread_cond_any = &cond; } void unlock() { lk.unlock(); self->set_clear_mutex.unlock(); } void lock() { std::lock(self->set_clear_mutex, lk); } ~custom_lock() { self->thread_cond_any = 0; self->set_clear_mutex.unlock(); } }; lock unlock exception이 발생하여도 무조건 unlock template<typename Lockable> void interruptible_wait(std::condition_variable_any& cv, Lockable& lk) { this_thread_interrupt_flag.wait(cv, lk); }
  • 24. C++ Concurrency in Action Study C++ Korea interruptible_wait for std::condition_variable_any DEMO !!!
  • 25. C++ Concurrency in Action Study C++ Korea DEMO 결과는 ??? 25 • 잘 동작함 • 뚤어보려 애썼는데… 안뚤림 ;;; • 작가님이 한가지만 더 살펴보자는데… std::future 같이 다른 blocking call에 interrupt를 주려면 ???
  • 26. C++ Concurrency in Action Study C++ Korea interrupting other blocking calls
  • 27. C++ Concurrency in Action Study C++ Korea interruptible_wait( ) using std::future 27 interrupt가 걸려도 빠져나가고 template<typename T> void interruptible_wait(std::future<T>& uf) { while (!this_thread_interrupt_flag.is_set()) { if (uf.wait_for(lk, std::future_status::ready == std::chrono::milliseconds(1))) break; } } 작업이 끝나도 빠져나가고 주기적으로 check
  • 28. C++ Concurrency in Action Study C++ Korea interrupting other blocking calls DEMO ??? Pass !!! 고마보자. 많이봤다. 아이가;;;
  • 29. C++ Concurrency in Action Study C++ Korea Handling interrupt 그동안 DEMO에서많이봤는데… 맹그거임.
  • 30. C++ Concurrency in Action Study C++ Korea Handling interrupt 30 딱히 설명이 필요할지… try { do_something(); } catch (thread_interrupted&) { handle_interrupt(); }
  • 31. C++ Concurrency in Action Study C++ Korea Handling interrupt 31 딱히 설명이 필요할지… try { do_something(); } catch (thread_interrupted&) { handle_interrupt(); } - 그런데, 이렇게 외부에서 exception을 처리 하는 경우, 만약 실수로 처리를 안하게 되면 ? std::terminate()가 호출되어 program이 종료 될 수도 있다. - 왠만하면 thread 내부에서 exception을 처리해 주는게 안전하다.
  • 32. C++ Concurrency in Action Study C++ Korea Handling interrupt in internal_thread constructor 32 아에 internal_thread 생성시 함수 실행 부분에서 exception 처리를 했다. template<typename FunctionType> interruptible_thread(FunctionType f) { std::promise<interrupt_flag*> p; internal_thread = std::thread([f, &p] { p.set_value(&this_thread_interrupt_flag); try { f(); } catch (thread_interrupted const&) { handle_interrupt(); } }); flag = p.get_future().get(); }
  • 33. C++ Concurrency in Action Study C++ Korea Summary 33 • 여러가지 방법으로 thread를 interrupt하는 방법을 살펴 봄. • while-loop 안에서 interruption_point( ) 체크 • std::condition_variable, std::condition_variable_any를 이용 • 다른 blocking 방법에 대한 예제 (std::future)
  • 34. C++ Concurrency in Action Study C++ Korea Q & A