头文件
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
thread
constructor
thread() noexcept;
thread( thread&& other ) noexcept;
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
thread( const thread& ) = delete;
thread 不可复制,没有两个 std::thread 对象可表示同一执行线程。
destructor
~thread();
Destroys the thread object.
If *this has an associated thread (joinable() == true), std::terminate() is called.
int main()
{
{
thread th1(t1); // th1离开作用域析构后,线程被终止;
cout << std::boolalpha << th1.joinable() << endl; // true
}
while (1);
return 0;
}
operator=
thread& operator=( thread&& other ) noexcept;
thread 不可复制,没有两个 std::thread 对象可表示同一执行线程。
joinable
thread::joinable() 用来判断线程对象是否持有一个活动的执行线程(执行实例)。以下情况的线程对象不持有实际线程:
- 缺省构造的thread对象
std::thread t1; // t1不是线程
t1.joinable(); // false
/////////////////////////////////////////////////
void f1(int n){
for (int i = 0; i < 2; ++i) {
std::cout << "Thread 1 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
std::thread t2(f1, n + 1);
t2.joinable(); // true
- 调用了thread::join()的对象
void t1() //普通的函数,用来执行线程
{
for (int i = 0; i < 5; ++i)
{
cout << "t1111" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main()
{
thread th1(t1);
cout << std::boolalpha << th1.joinable() << endl; // true
th1.join();
cout << std::boolalpha << th1.joinable() << endl;; // false
cout << "here is main\n\n";
while (1);
return 0;
}
- 调用了thread::detach()的对象
int main()
{
thread th1(t1);
cout << std::boolalpha << th1.joinable() << endl; // true
th1.detach();
cout << std::boolalpha << th1.joinable() << endl;; // false
cout << "here is main\n\n";
while (1);
return 0;
}
join
调用该函数会阻塞当前线程(主调线程)
阻塞调用者(caller)所在的线程(主调线程)直至被join的std::thread对象标识的线程(被调线程执行结束。
detach
detach是用来和线程对象分离的,这样线程可以独立地执行,一旦线程执行完毕,操作系统分配的资源将会被释放。不过这样由于没有thread对象指向该线程而失去了对它的控制。
当对象析构时线程会继续在后台执行,但是当主程序退出时并不能保证线程能执行完。
如果没有良好的控制机制或者这种后台线程比较重要,最好不用detach而应该使用join。
swap
交换两个线程对象所代表的底层句柄
mutex
std::mutex mux;
mux.lock();
mux.unlock();
lock
std::lock_guard , 与Mutex RAII
相关,方便线程对互斥量上锁。
std::unique_lock , 与Mutex RAII
相关,方便线程对互斥量上锁,但提供了更好的上锁和解锁控制。
std::mutex m;
std::lock_guard<mutex> lock1(m);
std::unique_lock<mutex> lock2(m);
condition_variable
#include <iostream>
#include <thread>
#include <stdlib.h>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
std::mutex mux;
std::condition_variable cond;
std::queue<int> q;
void producer()
{
for (int i = 0; i < 10; ++i)
{
std::unique_lock<mutex> lock(mux);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
q.push(i);
cond.notify_one();
}
}
void consumer()
{
while (1)
{
std::unique_lock<mutex> lock(mux);
while (q.empty())
{
cond.wait(lock);
}
cout << "consumer " << q.front() << endl;
q.pop();
}
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
cout << "producer finished " << endl;
t2.join();
return 0;
}