一 C++11多线程简介
C++11标准库会提供类thread
(std::thread
)。若要运行一个线程,可以创建一个类thread
的实体,其初始参数为一个函数对象,以及该函数对象所需要的参数。通过成员函数std::thread::join()
对线程会合的支持,一个线程可以暂停直到其它线程运行完毕。若有底层平台支持,成员函数std::thread::native_handle()
将可提供对原生线程对象运行平台特定的操作。对于线程间的同步,标准库将会提供适当的互斥锁(像是std::mutex
,std::recursive_mutex
等等)和条件参数(std::condition_variable
和std::condition_variable_any
)。前述同步机制将会以RAII锁(std::lock_guard
和std::unique_lock
)和锁相关算法的方式呈现,以方便程序员使用。
std::thread 在 #include<thread> 头文件中声明,因此使用 std::thread 时需要包含 #include<thread> 头文件。
1.创建一个线程
创建线程比较简单,使用std的thread实例化一个线程对象就创建完成了,示例:
#include <iostream>#include <thread>
using namespace std;
void t1()
{
for (int i = 0; i < 20; ++i)
{
cout << "t1111\n";
}
}
void t2()
{
for (int i = 0; i < 20; ++i)
{
cout << "t22222\n";
}
}
int main()
{
thread th1(t1);
thread th2(t2);
th1.join(); //等待th1执行完
th2.join(); //等待th2执行完
cout << "here is main\n\n";
return 0;
}
////////////////线程访问共享资源加锁定
使用mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去。
5.std::lock_guard
使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程。示例:
#include "stdafx.h"
#include<iostream>
#include<thread>
#include<mutex>
using namespace std;
const int N = 100000000;
int num = 0;
mutex m;
void t1()
{
lock_guard<mutex> lockGuard(m);
for (int i = 0; i < N; i++)
{
num++;
}
}
void t2()
{
lock_guard<mutex> lockGuard(m);
for (int i = 0; i < N; i++)
{
num++;
}
}
int main()
{
clock_t start = clock();
thread th1(t1);
thread th2(t2);
th1.join();
th2.join();
clock_t end = clock();
cout << "num=" << num << ",用时 " << end - start << " ms" << endl;
return 0;
}