1 분 소요

1. std::thread

  • c++ 표준 스레드 라이브러리
  • 헤더 파일에 포함
  • OS API의 스레드 사용보다 사용하기 쉬움

2. 스레드 방법

2.1. 스레드 종료까지 대기

  • join() 함수를 사용하여 스레드가 종료할 때까지 대기
  • join을 사용하면 blocking

2.2. 스레드 식별자

  • get_id()를 통해 해당 스레드의 식별자를 얻을 수 있음
//cpp
std::thread Thread1;
Thread1.get_id()

std::this_thread::get_id()

2.3. 스레드 object와 커널 스레드 분리

  • detach 함수를 사용하면 thread object와 thread의 연결고리를 떼어냄
  • detach 이후에는 thread object는 thread를 제어할 수 없음

2.4. 일시 중지와 양보

  • sleep_for, sleep_until을 사용하면 스레드를 일시중지 시킬 수 있음
    • sleep_for : 지정한 시간동안
    • sleep_until : 지정시간까지
  • yield 를 사용하여 자신(스레드)의 활동을 포기하고 다른 스레드에게 양보
//cpp
std::this_thread::yield();

3. 공유 자원 사용하기

  • 멀티스레드 프로그래밍에서는 공유 자원 관리가 가장 큰 문제
    • 너무 빡빡하게 관리하면 성능 하락
    • 너무 느슨하게 관리하면 시한 폭탄 동작
  • mutex를 사용하여 공유 리소스를 관리하는 것이 일반적임
    • mutex는 Windows에 구현에서는 critical section (임계 영역)을 사용

3.1. 공유자원 사용할 수 있는지 조사

  • 스레드 A가 mutex의 lock을 호출 했을 때, 이미 스레드 B에서 lock을 호출했다면 A는 B가 lock을 풀어줄 때까지 대기한다
  • 스레드A는 다른 일을 하고 싶어도 할 수가 없음 ( 이럴 때 try_lock()을 사용 )
  • 다른 스레드가 먼저 락을 걸었다면 대기하지 않고 즉시 false를 반환
  • 반대로 true를 반환한 경우 공유 리소스의 소유권을 가짐

3.2. 자동으로 lock 풀기

  • 실수 lock 호출 후 unlock을 안했으면 데드락 상황에 빠짐 or 코드 실행 중 예외가 발생하여 lock을 풀지 못하는 경우
  • 이런 문제를 풀기 위해 lock_guard 라는 유틸리티 클래스를 사용
  • scope를 벗어날 때 자동으로 unlock 을 호출
// cpp, 클래스 생성 후 특정한 시기에 스레드를 만들어서 동작시킴
#include <mutex>
#include <thread>
#include <iostream>

int main(){
  std::mutex mtx_lock;

  std::thread Threads1([&]()
  {
    for (int i = 0 ; i < 5; ++i)
    {
      std::lock_guard<std::mutex> guard(mtx_lock);
      std::cout << "Thread1 Num : " << i << " " << std::this_thread::get_id() <<std::endl;
      // mtx_lock.unlock();
    }
  });

  Threads1.join();
}

3.3. 반복하여 lock 걸기

// cpp
std::recursive_mutext m_mtx; // 사용

3.4. 딱 한번만 실행

  • 멀티스레드 환경에서 프로그램 실행 중에서 단 한번만의 코드 실행이 필요할 때
//cpp
std::once_flag p_flag;
void Test()
{
	// something
}

int main()
{
	for ( ... )
	{
		std::call_once(p_flag, Test);
	}
}

참고

모두의 코드


This is personal diary for study documents.
Please comment if I'm wrong or missing something else 😄. 

Top

댓글남기기