C++/Library
2021. 3. 30. 00:03
mutex
<mutex>
라이브러리Mutual Exclusion의 약자이다.
예제
mutex
를 적용하지 않은 예제- 출력이 섞여서 나오는 것을 볼 수 있다.
#include <iostream> #include <thread> #include <chrono> int main() { using namespace std; const int num_logical_processors = std::thread::hardware_concurrency(); cout << "Number of processors : " << num_logical_processors << endl; cout << "ID of this thread : " << std::this_thread::get_id() << endl; auto work_func = [](const string& name) { for (int i = 0; i < 5; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); cout << name << ' ' << std::this_thread::get_id() << " is working " << i << endl; } }; std::thread t1 = std::thread(work_func, "Jack Jack"); std::thread t2 = std::thread(work_func, "Dash"); t1.join(); t2.join(); } /* stdout stderr Number of processors : 12 ID of this thread : 16040 Jack Jack 5336 is working 0 Dash 8368 is working 0 Jack Jack 5336 is working 1Dash 8368 is working 1 Dash 8368 is working 2 Jack Jack 5336 is working 2 Dash 8368 is working 3 Jack Jack 5336 is working 3 Jack Jack 5336 is working 4 Dash 8368 is working 4 */
mutex
를 사용한 예제#include <iostream> #include <thread> #include <chrono> #include <mutex> int main() { using namespace std; mutex mtx; const int num_logical_processors = std::thread::hardware_concurrency(); cout << "Number of processors : " << num_logical_processors << endl; cout << "ID of this thread : " << std::this_thread::get_id() << endl; auto work_func = [&](const string& name) { for (int i = 0; i < 5; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); mtx.lock(); cout << name << ' ' << std::this_thread::get_id() << " is working " << i << endl; mtx.unlock(); } }; std::thread t1 = std::thread(work_func, "Jack Jack"); std::thread t2 = std::thread(work_func, "Dash"); t1.join(); t2.join(); } /* stdout stderr Number of processors : 12 ID of this thread : 1588 Jack Jack 17596 is working 0 Dash 14068 is working 0 Jack Jack 17596 is working 1 Dash 14068 is working 1 Dash 14068 is working 2 Jack Jack 17596 is working 2 Jack Jack 17596 is working 3 Dash 14068 is working 3 Dash 14068 is working 4 Jack Jack 17596 is working 4 */
- 만약
mutex.unlock()
을 하지 않으면 다른 쓰레드에서 해당 자원을 사용할 수 없다.
- 만약
C++11
lock_guard
mutex.lock()
,mutex.unlock()
을 사용하지 않고, 정의하면 락이 걸리고 영역을 벗어나면 언락을 해주는 클래스이다.C++17부터는 템플릿타입 자리에 아무것도 안넣어도 된다. (
lock_guard lock(mtx)
이런 식으로)#include <iostream> #include <thread> #include <chrono> #include <mutex> int main() { using namespace std; int shared_memory(0); mutex mtx; auto count_func = [&]() { for (int i = 0; i < 1000; ++i) { this_thread::sleep_for(chrono::milliseconds(1)); lock_guard<mutex> lock(mtx); shared_memory++; } }; thread t1 = thread(count_func); thread t2 = thread(count_func); t1.join(); t2.join(); cout << "Value is " << shared_memory << endl; } /* stdout stderr Value is 2000 */
C++17
scoped_lock
뮤텍스 락을 자주 걸면 오버헤드가 커지므로 성능 저하가 발생한다.
lock_guard
에서 여러mutex
를 한번에 lock할 수 있는 기능을 추가한 클래스라고 한다. 즉 상위 호환이다.#include <iostream> #include <thread> #include <chrono> #include <mutex> int main() { using namespace std; int shared_memory(0); mutex mtx; auto count_func = [&]() { for (int i = 0; i < 1000; ++i) { this_thread::sleep_for(chrono::milliseconds(1)); scoped_lock<mutex> lock(mtx); shared_memory++; } }; thread t1 = thread(count_func); thread t2 = thread(count_func); t1.join(); t2.join(); cout << "Value is " << shared_memory << endl; } /* stdout stderr Value is 2000 */
'C++ > Library' 카테고리의 다른 글
C++ 멀티쓰레딩 (Multithreading) (0) | 2021.03.30 |
---|---|
C++ atomic (0) | 2021.03.30 |
C++ 파일 임의 위치 접근 (0) | 2021.03.29 |
C++ fstream (0) | 2021.03.29 |
C++ 정규 표현식 (Regular Expressions) (0) | 2021.03.29 |