1 분 소요

개요

  • 단일 실행 스레드
  • 생성자의 인자로 전달된 함수를 객체 생성 즉시 실행
  • spurious wakeup에 유의
  • 멤버 함수
    • observers
      • joinable()
        • 조인 가능 여부 반환
      • get_id()
        • 스레드 아이디 반환
      • native_handle()
        • 스레드 핸들을 반환
      • hardware_concurrency()
        • 지원하는 동시 스레드 수 반환
    • operations
      • join()
        • 스레드가 실행을 완료할 때까지 대기
      • detach()
        • 스레드가 스레드 핸들과 독립적으로 실행되도록 허용
      • swap()
        • 두 개의 스레드 객체를 교환


예제

  • 코드
    #include <atomic>
    #include <chrono>
    #include <condition_variable>
    #include <iostream>
    #include <map>
    #include <mutex>
    #include <queue>
    #include <string>
    #include <thread>
    #include <vector>

    using namespace std;

    atomic<bool> condition;
    mutex m;
    mutex mCV;
    condition_variable cv;
    queue<string> q;

    void producer(const string &content) {
    	if (condition == false) {
    		return;
    	}

    	{
    		lock_guard<mutex> lock(m);
    		q.push(content);
    		cout << "push : " << this_thread::get_id() << " : " << content << endl;
    	}

    	cv.notify_one();

    	this_thread::sleep_for(chrono::seconds(1));
    }

    void consumer() {
    	while (condition) {
    		{
    			unique_lock<mutex> lock(mCV);
    			cv.wait(lock, [&]() { return q.size() || condition == false; });
    			if (q.empty() && condition == false) {
    				break;
    			}

    			{
    				lock_guard<mutex> lock(m);
    				cout << "front : " << this_thread::get_id() << " : "
    					 << q.front() << endl;
    				q.pop();
    			}
    		}
    	}
    }

    void run() {
    	cout << "thread::hardware_concurrency() : "
    		 << thread::hardware_concurrency() << endl;

    	thread t([]() {
    		cout << "this_thread::get_id() : " << this_thread::get_id() << endl;
    	});

    	cout << "t.get_id() : " << t.get_id() << endl;

    	cout << "t.joinable() : " << t.joinable() << endl;
    	t.join();
    	cout << "t.joinable() : " << t.joinable() << endl;

    	cout << endl << "------" << endl << endl;

    	condition.store(true);

    	vector<thread> v1;
    	v1.clear();

    	map<int, thread> m1;
    	m1.clear();
    	for (int i = 0; i < 3; ++i) {
    		//		m1[i] = thread(producer, to_string(i));
    		v1.push_back(thread(producer, to_string(i)));
    	}

    	vector<thread> v2;
    	v2.clear();

    	map<int, thread> m2;
    	m2.clear();
    	for (int i = 0; i < 3; ++i) {
    		//		m2[i] = thread(consumer);

    		v2.push_back(thread(consumer));
    	}

    	for (auto &iter : v1) {
    		iter.join();
    	}

    	condition.store(false);
    	cv.notify_all();

    	for (auto &iter : v2) {
    		//		cout << iter.get_id() << " : joinable 1 - " << iter.joinable()
    		//<< endl;
    		iter.join();
    		//		cout << iter.get_id() << " : joinable 2 - " << iter.joinable()
    		//<< endl;
    	}
    }

    int main() {
    	run();

    	return 0;
    }
  • 실행 결과
    thread::hardware_concurrency() : 2
    t.get_id() : 140429792114240
    t.joinable() : 1
    this_thread::get_id() : 140429792114240
    t.joinable() : 0

    ------

    push : 140429792114240 : 0
    push : 140429783721536 : 1
    push : 140429775328832 : 2
    front : 140429766936128 : 0
    front : 140429766936128 : 1
    front : 140429766936128 : 2