Updated:

1 minute read

개요

  • 단일 실행 스레드
  • 생성자의 인자로 전달된 함수를 객체 생성 즉시 실행
  • 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