文章目录
- 线程创建方式
- mutex
- 条件变量
- atomic
线程创建方式
头文件
#include<thread>
线程创建传个可执行对象就可以,如函数指针,仿函数,lambda,包装器。后面的Args是可变参数包。
使用函数指针创建线程
void fun(int& a)
{a = 1;cout << "thread: void fun()" << endl;
}
首先传可执行对象,参数传后面thread的Args会解析参数包,引用参数需要+ref()。
int a = 0;
thread t1(fun,ref(a));
t1.join();
cout << a << endl;
使用lambda创建线程
int a = 0;
thread t2([&]() {a = 3;cout << "lambda" << endl;});
t2.join();
cout << a << endl;
线程创建后需要join等待回收线程的资源。
mutex
头文件
#include<mutex>
锁不能被拷贝。
创建多个线程时对于需要访问的同一个变量通常需要加锁,否则会有线程安全问题。
创建一个锁并在临界区进行加锁。
mutex mtx;
int a = 0;
thread t1([&]() {for (int i = 0; i < 10000; i++){mtx.lock();a++;mtx.unlock();}
});
thread t2([&]() {for (int i = 0; i < 10000; i++){mtx.lock();a++;mtx.unlock();}
});
t1.join();
t2.join();
cout << a << endl;
也可使用lock_guard利用RAII自动加锁解锁
template<class T>
class Lock_Guard
{
public:Lock_Guard(T& mtx):_mtx(mtx){_mtx.lock();}~Lock_Guard(){_mtx.unlock();}
private:T& _mtx;
};
条件变量
创建一个条件变量
condition_variable cv;
wait可以让线程在这里阻塞等待,直到被其他线程唤醒,在等待前会自动unlock解锁,被唤醒时会自动加上锁。
mutex mtx;
condition_variable cv;
unique_lock<mutex> lock(mtx);
cv.wait(lock);
notify_one随机唤醒一个线程,notify_all唤醒所有其他线程。
cv.notify_one();
cv.notify_all();
创建三个线程交替打印数字
int main()
{mutex mtx;condition_variable cv;int flag = 0;int a = 0;thread t1([&]() {for (int i = 0; i < 10; i++){unique_lock<mutex> lock(mtx);while (flag!=0)cv.wait(lock);flag = 1;a++;std::cout << "thread t1" << ": " << a << endl;cv.notify_all();}});thread t2([&]() {for (int i = 0; i < 10; i++){unique_lock<mutex> lock(mtx);while (flag!=1)cv.wait(lock);flag = 2;a++;std::cout << "thread t2" << ": " << a << endl;cv.notify_all();}});thread t3([&]() {for (int i = 0; i < 10; i++){unique_lock<mutex> lock(mtx);while (flag!=2)cv.wait(lock);flag = 0;a++;std::cout << "thread t3" << ": " << a << endl;cv.notify_all();}});t1.join();t2.join();t3.join();return 0;
}
atomic
#include<atomic>
原子库,使用CAS操作比较和交换实现无锁编程。
这样就不需要加锁了