boost是C++的测试版本,许多C++的新特性会在这里测试,待时机成熟后悔合并到C++中。boost的C++特性也是稳定的,但不是C++自带,需要编译成库引用。
一个std::thread对象只可能处于可联结或不可联结两种状态之一:
综上:std::thread对象析构时,会先判断是否可joinable(),如果可联结,则程序会直接被终止出错。这意味着创建thread对象以后,必须要在随后的某个地方调用join或detach以便让std::thread处于不可联结状态。
join():等待子线程执行,调用线程(如主线程)处于阻塞。join()执行完成之后,底层线程id被设置为0,即joinable()变为false。
detach():分离子线程,与当前线程的连接被断开,joinable()变为false,子线程成为后台线程,被C++运行时库接管。此时子线程与主线程并行运行。不过这样由于没有thread对象指向该线程而失去了对它的控制,当对象析构时线程会继续在后台执行,但是当主程序退出时并不能保证线程能执行完(退出thread_func即是执行完子线程)。如果没有良好的控制机制或者这种后台线程比较重要,最好不用detach而应该使用join。
# 声明要求的 cmake 最低版本
cmake_minimum_required(VERSION 3.2)
# 声明一个 cmake 工程
project(thread_demo)
add_definitions(-std=c++11)
# 添加一个可执行程序
# 语法: add_executable( 程序名 源代码文件 )
add_executable(thread_demo src/main.cpp)
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(thread_demo pthread)#thread库
#include
#include
using namespace std;
bool close_thread = false;//设置一个标志位,用于退出子线程
void subThread() {
while(1){
if (close_thread)
break;//跳出函数,或者执行完函数,就认为子线程接收
std::cout << "sub thread" << std::endl;
}
}
int main(int argc, char* argv[]) {
thread sub_thread(subThread); //实例化一个线程对象sub_thread,该线程开始执行
std::cout << "main thread" << std::endl;
close_thread = true;//告诉要退出程序了,子线程也要退出
sub_thread.join(); //使不可联结
return 0;
}
头文件是#include
,该头文件主要声明了与互斥量(mutex)相关的类,包括 std::mutex 系列类,std::lock_guard, std::unique_lock, 以及其他的类型和函数。
mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。
#include
#include
#include
using namespace std;
mutex m;
int cnt = 10;
void thread1() {
while (cnt > 5){
m.lock();
if (cnt > 0) {
--cnt;
cout << cnt << endl;
}
m.unlock();
}
}
void thread2() {
while (cnt > 0) {
m.lock();
if (cnt > 0) {
cnt -= 10;
cout << cnt << endl;
}
m.unlock();
}
}
int main(int argc, char* argv[]) {
thread th1(thread1); //实例化一个线程对象th1,该线程开始执行
thread th2(thread2);
th1.join();
th2.join();
cout << "main..." << endl;
return 0;
}
但是:mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去,因为mutex还是保持锁着的状态。
使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程。
#include
#include
#include
using namespace std;
mutex m;
int cnt = 10;
void thread1() {
while (cnt > 5){
lock_guard lockGuard(m);
if (cnt > 0) {
--cnt;
cout << cnt << endl;
}
}
}
void thread2() {
while (cnt > 0) {
lock_guard lockGuard(m);
if (cnt > 0) {
cnt -= 10;
cout << cnt << endl;
}
}
}
int main(int argc, char* argv[]) {
thread th1(thread1); //实例化一个线程对象th1,该线程开始执行
thread th2(thread2);
th1.join();
th2.join();
cout << "main..." << endl;
return 0;
}