Skip to content

2014 10 21 스레드, 스레드 로컬 저장소

krikit edited this page Nov 26, 2014 · 1 revision

화면 출력 동기화

여러 스레드에서 동시에 화면으로 출력하다보면 출력이 뒤섞여서 알아보기 힘든 경우가 있습니다. 이럴 경우 아래 한줄의 코드를 삽입해 주면 깔끔하게 나옵니다.

std::cout.sync_with_stdio(true);

함수 객체를 이용한 스레드 생성

함수 객체란 operator()를 구현한 객체를 말합니다. 즉, 객체를 생성하고 객체에 "()"를 붙여 호출하는 식으로 사용하여 마치 객체를 호출하는 것처럼 사용하는 것을 말합니다. C++11에서 새로이 도입된 스레드를 구동할 때에도 이러한 함수 객체를 이용할 수 있습니다.

#include <thread>

class MyThread {
 public:
  void operator()() const {
    // 스레드 동작 함수
  }
};

std::thread t1{MyThread()};    // 유니폼 초기화를 통해 함수 객체를 이용해 스레드 생성
std::thread t2(MyThread());    // 컴파일 에러
std::thread t3((MyThread()));    // 정상

위의 코드에서 t2 객체를 괄호를 통해 생성할 때, 함수 객체의 인자가 없는 경우 컴파일러가 함수를 정의하는 코드로 취급하여 에러가 발생합니다. 따라서 인자가 없는 함수 객체를 이용하여 스레드를 생성할 경우 유니폼 초기화를 이용하는 것이 좋습니다.

람다 표현식을 이용한 스레드 생성

C++11에는 람다 표현식이 있는데요, 이를 이용하여 스레드를 생성할 수도 있습니다.

std::thread t([](int arg1, int arg2) {
      // 스레드 동작 함수
    }, 1, 2);

위 코드처럼 람다 함수의 인자는 스레드의 생성자에서 람다 표현식 뒤에 차례로 넣어주면 됩니다.

객체의 메서드를 이용한 스레드 생성

전역 함수, 함수 객체 혹은 람다 표현식 외에 객체의 메서드를 이용해서 스레드를 생성하는 것도 가능합니다.

class MyClass {
 public:
  void do_something() {
    // 스레드 동작 함수
  }
};

MyClass obj;
std::thread t(&MyClass::do_something, &obj);

스레드 로컬 저장소

스레드 로컬 저장소(Thread Local Storage, TLS)는 스레드 별로 전역 변수를 별도로 가질 수 있도록 지원하는 기능을 말합니다. C++11에서는 이를 위해 thread_local이란 새로운 키워드를 제공합니다.

thread_local int n;

int main(int argc, char** argv) {
  return 0;
}

위 코드에서 n은 전역 변수로서 모든 스레드가 공유해야 하지만, thread_local 키워드를 통해 각각의 스레드가 별도의 저장 공간을 가지게 되고, 초기화도 각각 한번씩 일어나게 됩니다.

Clone this wiki locally