728x90
반응형

thread 8

COM/ATL을 Thread 내에서 사용하기

COM/ATL로 만든 기능을 다이얼로그 등에서 작업할 때에는 정상적으로 동작하지만, Thread 속에 넣으면 에러가 발생하는 경우가 있다. 이때는 스레드에서 사용함을 초기화해야 한다. CoInitializeEx(NULL, COINIT_MULTITHREADED); // COM 시작 시 ::CoUninitialize(); // 종료 시 해당 코드를 CoCreateInstance() 사용 전과 프로그램이 닫히기 전에 추가하면 스레드에서도 정상적으로 사용할 수 있다.

[C++] unique_lock, lock_guard

unique_lock과 lock_guard의 차이점은 lock을 걸 수 있는 시점이다. 둘 다 소멸 시점에 lock이 걸려 있다면 unlock을 수행한다. lock_guarud는 lock과 unlock 사이에서 lock과 unlock을 할 수 없지만 unique_lock은 소멸하기 전에 unlock과 lock을 걸 수 있다. unique_lock은 lock_guard에 기능이 추가된 버전이라고 생각하면 된다. 이러한 lock 유틸리티 객체를 사용하는 것은 프로그래머가 unlock 코드에 신경 쓰지 않아도 되게 해 준다. 아래와 같이 사용하면 된다. std::mutex m_mutex; std::lock_guard lock(m_mutex); std::unique_lock lock(m_mutex);

[C++] std::thread 종료 (abort() has been called)

std::thread를 사용하다 보면 abort() has been called라는 에러 메시지를 만나는 경우가 있다. 이는 thread가 종료되기 전에 시스템이 종료되거나, 객체가 사라질 때 발생한다. 이 때는 join()을 사용해서 해결하면 된다. #include #include using namespace std; int total; void sum() { for (int i = 0; i < 200000; i++) total += 1; } int main() { while (1) { total = 0; std::thread th1(sum); std::thread th2(sum); cout

[C++] std::async

std::async는 std::task 클래스 기반으로 만들어진 클래스로 thread를 만들 때 사용한다. std::async는 std::thread와 달리 내부적으로 thread pool을 만들어 thread를 관리하며 std::thread보다 안정적이며 프로그래머가 사용하기 편하다. std::async는 반환 값을 std::future로 받는다. #include #include using namespace std; void print(char id) { for (int i = 0; i < 10; i++) { printf("thread no : %c , Count : %d \n", id, i); } } int main() { std::future a = std::async(std::launch::asy..

[C++] thread_local

thread_local은 thread가 TLS(Thread Local Storage)를 지원하기 위해서 C++11부터 추가되었다. 기존에 TLS변수를 선언하기 위해서는 __declspec(thread)를 사용해야만 했다. 하지만 정식으로 thread_local가 도입됨으로 간편하게 사용할 수 있게 되었다. TLS(Thread Local Storage) : thread 별로 고유한 저장공간을 가질 수 있는 방법이다. 각각의 thread는 고유한 Stack을 가지기 때문에 Stack 변수(지역 변수)는 thread별로 고유하다. 그래서 각각의 thread가 같은 함수를 실행한다고 해도 그 함수에서 정의된 지역 변수는 실제로 서로 다른 메모리 공간에 위치한다는 의미다. 그러나 정적 변수와 전역 변수의 경우에는..

[C++] recursive_mutex

std::mutex의 lock()의 경우 lock을 호출한 함수에서 unlock을 호출하지 않고 또다시 lock을 호출하면 알 수 없는 동작을 하게 된다고 한다. 예를 들면 아래와 같다. class buffer { list queue; std::mutex mut; public: bool empty() { std::lock_guard lock(mut); return queue.empty(); } // 생략 int pop() throw(out_of_range) { std::lock_guard lock(mut); while (empty()) { // 생략 } int tmp = queue.front(); queue.pop_front(); return tmp; } }; buffer 클래스에서 pop() 함수를 호..

[C++] condition_variable

thread를 수행할 때 때로는 다른 thread의 작업을 기다려야 할 때가 있다. 이때 condition_varialbe을 사용하면 thread를 block 할 수 있다. block 조건은 timeout을 설정할 수 도 다른 thread를 통해 설정할 수도 있다. condition_variable은 다음과 같은 method를 제공한다. notify_one : 해당 조건 변수를 기다리고 있는 thread 중 한 개의 thread를 깨운다. notify_all : 해당 조건 변수를 기다리고 있는 모든 thread를 깨운다. thread는 상기 method 이외에 timeout에 의해서 깨어날 수도 있다. #include #include #include using namespace std; mutex g_m..

[C++] thread에서 return 값 받기 (promise/future)

C++11 이후에는 이 추가되었으며 future, promise를 통해서 값이나 예외를 저장할 수 있다. 생성하려는 Thread에 Promise를 매개변수로 전달해서 받아올 수 있다. 미래에(future) thread가 원하는 데이터를 돌려 주겠다고 약속(promise)하는 것이라고 할 수 있다. #include #include #include #include void ThreadFunc(std::promise& retVal) { retVal.set_value(1); } int main() { std::promise p; std::future f = p.get_future(); std::thread th1(ThreadFunc, std::ref(p)); th1.join(); std::cout

728x90
반응형