SlideShare a Scribd company logo
1 of 34
Download to read offline
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

What's hot

[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...
[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...
[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when c...
Seok-joon Yun
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
문익 장
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11
흥배 최
 

What's hot (20)

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

Viewers also liked

Dieznuevascompetenciasparaensear 110405165528-phpapp01
Dieznuevascompetenciasparaensear 110405165528-phpapp01Dieznuevascompetenciasparaensear 110405165528-phpapp01
Dieznuevascompetenciasparaensear 110405165528-phpapp01
alarconx
 
CV_ Ngo Xuan Cam Thu_UPDATED 160301
CV_ Ngo Xuan Cam Thu_UPDATED 160301CV_ Ngo Xuan Cam Thu_UPDATED 160301
CV_ Ngo Xuan Cam Thu_UPDATED 160301
Thu Ngô Xuân Cẩm
 

Viewers also liked (20)

Concurrency in action - chapter 5
Concurrency in action - chapter 5Concurrency in action - chapter 5
Concurrency in action - chapter 5
 
Pro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, PerformancePro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, Performance
 
Concurrency in action - chapter 7
Concurrency in action - chapter 7Concurrency in action - chapter 7
Concurrency in action - chapter 7
 
Dieznuevascompetenciasparaensear 110405165528-phpapp01
Dieznuevascompetenciasparaensear 110405165528-phpapp01Dieznuevascompetenciasparaensear 110405165528-phpapp01
Dieznuevascompetenciasparaensear 110405165528-phpapp01
 
Autoformas
Autoformas Autoformas
Autoformas
 
Final Presentation MNFPC
Final Presentation MNFPCFinal Presentation MNFPC
Final Presentation MNFPC
 
La energía
La energíaLa energía
La energía
 
Imagenes animación
Imagenes   animaciónImagenes   animación
Imagenes animación
 
Lenguaje en C
Lenguaje en CLenguaje en C
Lenguaje en C
 
Telemarketing services: Make Your Marketing Campaign More Productive
Telemarketing services: Make Your Marketing Campaign More ProductiveTelemarketing services: Make Your Marketing Campaign More Productive
Telemarketing services: Make Your Marketing Campaign More Productive
 
Norma Hurtado
Norma HurtadoNorma Hurtado
Norma Hurtado
 
Badania satysfakcji klienta z platformą Webankieta
Badania satysfakcji klienta z platformą WebankietaBadania satysfakcji klienta z platformą Webankieta
Badania satysfakcji klienta z platformą Webankieta
 
CV -linked in
CV -linked inCV -linked in
CV -linked in
 
Film referencing a2
Film referencing a2Film referencing a2
Film referencing a2
 
Post card analysis
Post card analysisPost card analysis
Post card analysis
 
Integrating spirituality 1.0
Integrating spirituality 1.0Integrating spirituality 1.0
Integrating spirituality 1.0
 
Biblical worldview
Biblical worldviewBiblical worldview
Biblical worldview
 
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
 
CV_ Ngo Xuan Cam Thu_UPDATED 160301
CV_ Ngo Xuan Cam Thu_UPDATED 160301CV_ Ngo Xuan Cam Thu_UPDATED 160301
CV_ Ngo Xuan Cam Thu_UPDATED 160301
 
Resumeforthestate
ResumeforthestateResumeforthestate
Resumeforthestate
 

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

Smc–state machinecompiler
Smc–state machinecompilerSmc–state machinecompiler
Smc–state machinecompiler
Dong Hyeun Lee
 
Android+init+process
Android+init+processAndroid+init+process
Android+init+process
Hong Jae Kwon
 
Clean code
Clean codeClean code
Clean code
bbongcsu
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기
Heo Seungwook
 
파이썬 스터디 15장
파이썬 스터디 15장파이썬 스터디 15장
파이썬 스터디 15장
SeongHyun Ahn
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
Ryan Park
 

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

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

More from Seok-joon Yun

[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
Seok-joon Yun
 

More from Seok-joon Yun (20)

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