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

What's hot (20)

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

Viewers also liked (20)

PDF
Concurrency in action - chapter 5
JinWoo Lee
 
PPTX
Pro typescript.ch07.Exception, Memory, Performance
Seok-joon Yun
 
PDF
Concurrency in action - chapter 7
JinWoo Lee
 
PPT
Dieznuevascompetenciasparaensear 110405165528-phpapp01
alarconx
 
DOCX
Autoformas
America Mar
 
PPTX
Final Presentation MNFPC
Oliver McCluskey
 
PPT
La energía
Conchi Cantero H
 
PPTX
Imagenes animación
America Mar
 
PDF
Lenguaje en C
Alvaro Martinez Jimenez
 
PPTX
Telemarketing services: Make Your Marketing Campaign More Productive
Jennifer Aniston
 
PPTX
Norma Hurtado
José María
 
PDF
Badania satysfakcji klienta z platformą Webankieta
Webankieta
 
DOCX
CV -linked in
Devon Ford
 
PPTX
Film referencing a2
Rabiahussain50
 
PPTX
Post card analysis
rabiahusain12345
 
PPT
Integrating spirituality 1.0
Sri Joydip
 
PPT
Biblical worldview
Andrew Timberlake
 
PDF
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
Evelina Ceccato
 
PDF
CV_ Ngo Xuan Cam Thu_UPDATED 160301
Thu Ngô Xuân Cẩm
 
DOCX
Resumeforthestate
vincent moreno
 
Concurrency in action - chapter 5
JinWoo Lee
 
Pro typescript.ch07.Exception, Memory, Performance
Seok-joon Yun
 
Concurrency in action - chapter 7
JinWoo Lee
 
Dieznuevascompetenciasparaensear 110405165528-phpapp01
alarconx
 
Autoformas
America Mar
 
Final Presentation MNFPC
Oliver McCluskey
 
La energía
Conchi Cantero H
 
Imagenes animación
America Mar
 
Telemarketing services: Make Your Marketing Campaign More Productive
Jennifer Aniston
 
Norma Hurtado
José María
 
Badania satysfakcji klienta z platformą Webankieta
Webankieta
 
CV -linked in
Devon Ford
 
Film referencing a2
Rabiahussain50
 
Post card analysis
rabiahusain12345
 
Integrating spirituality 1.0
Sri Joydip
 
Biblical worldview
Andrew Timberlake
 
Logica booleana, motori di ricerca e valutazione dell'informazione nel web. L...
Evelina Ceccato
 
CV_ Ngo Xuan Cam Thu_UPDATED 160301
Thu Ngô Xuân Cẩm
 
Resumeforthestate
vincent moreno
 
Ad

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

PDF
[143] Modern C++ 무조건 써야 해?
NAVER D2
 
PPTX
Smc–state machinecompiler
Dong Hyeun Lee
 
PPTX
Design Pattern - Multithread Ch10
hyun soomyung
 
PPTX
불어오는 변화의 바람, From c++98 to c++11, 14
명신 김
 
PDF
Basic git-commands
insanehong Kim
 
PDF
Effective c++ chapter1 2_dcshin
Dong Chan Shin
 
PDF
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
Seok-joon Yun
 
PPTX
Android+init+process
Hong Jae Kwon
 
PDF
[1B4]안드로이드 동시성_프로그래밍
NAVER D2
 
PPTX
Clean code
bbongcsu
 
PDF
Lambda 란 무엇인가
Vong Sik Kong
 
PDF
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
NAVER D2
 
PDF
MutiCore 19-20
HyeonSeok Choi
 
PPTX
Multi-thread : producer - consumer
Chang Yoon Oh
 
PPTX
javascript02
ChangHyeon Bae
 
PPTX
C++ 프로젝트에 단위 테스트 도입하기
Heo Seungwook
 
PPTX
파이썬 스터디 15장
SeongHyun Ahn
 
PPT
카사 공개세미나1회 W.E.L.C.
Ryan Park
 
PPTX
About Visual C++ 10
흥배 최
 
PDF
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
 
[143] Modern C++ 무조건 써야 해?
NAVER D2
 
Smc–state machinecompiler
Dong Hyeun Lee
 
Design Pattern - Multithread Ch10
hyun soomyung
 
불어오는 변화의 바람, From c++98 to c++11, 14
명신 김
 
Basic git-commands
insanehong Kim
 
Effective c++ chapter1 2_dcshin
Dong Chan Shin
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
Seok-joon Yun
 
Android+init+process
Hong Jae Kwon
 
[1B4]안드로이드 동시성_프로그래밍
NAVER D2
 
Clean code
bbongcsu
 
Lambda 란 무엇인가
Vong Sik Kong
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
NAVER D2
 
MutiCore 19-20
HyeonSeok Choi
 
Multi-thread : producer - consumer
Chang Yoon Oh
 
javascript02
ChangHyeon Bae
 
C++ 프로젝트에 단위 테스트 도입하기
Heo Seungwook
 
파이썬 스터디 15장
SeongHyun Ahn
 
카사 공개세미나1회 W.E.L.C.
Ryan Park
 
About Visual C++ 10
흥배 최
 
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
 
Ad

More from Seok-joon Yun (20)

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

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 박 동하 ([email protected]) C++ Korea 윤석준 ([email protected])
  • 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