c11提供了线程的标准库

lamda表达式
左值引用
完美转发forward
队列queue
emplace
可变参数
模板函数
万能引用
右值引用
函数适配器bind
时间库chrono

线程库的使用

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<thread>

void func()
{
std::cout<<"线程启动"<<std::endl;
}
int main(){
std::thread th1();
return 0;
}

lock_guard

lock_guard是C++11提供的锁管理机制,能够对共享变量进行自动加锁和解锁。

初始化

1
std::lock_guard<std::mutex> guard(mux);

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename _Mutex>
class lock_guard
{
public:
typedef _Mutex mutex_type;

explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }

lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
{ } // calling thread owns mutex

~lock_guard()
{ _M_device.unlock(); }

lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;

private:
mutex_type& _M_device;
};

构造函数调用时加锁,离开作用域,调用析构函数时,进行解锁。

1
2
lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
{ } // calling thread owns mutex

意味着已经加锁,只需要利用虚构函数

unique_lock

lock_guard拥有的特性,unique_lock也同样拥有

1
std::unique_lock<std::mutex> ul(mux);

自行加锁

1
std::unique_lock<std::mutex> ul(mux,std::defer_lock);

延时加锁需要和时间锁配合使用

1
2
3
std::timed_mutex mux;
std::unique_lock<std::timed_mutex> ul(mux,std::defer_lock);
ul.try_lock_for(std::chrono::seconds(5));

call_once

单例对象

懒汉模式

1
2
3
4
5
6
7
8
9
10
class Log {
Log(){};
Log(const Log& log)=delete;
Log& operator=(const Log& log)=delete;
static Log& getInstance(){
static Log log;
return log;
}

};

饿汉模式

1
2
3
4
5
6
7
8
9
10
class Log {
Log(){};
Log(const Log& log)=delete;
Log& operator=(const Log& log)=delete;
static Log& getInstance(){
static Log* log= nullptr;
if(!log){log=new Log();}
return *log;
}
};
1
2
std::once_flag once;
std::call_once(once,function);

条件变量

1
#include<condition_variable>
1
2
3
4
5
6
7
8
9
10
11
class condition_variable
{
//....
template<typename _Predicate>
void
wait(unique_lock<mutex>& __lock, _Predicate __p)
{
while (!__p())
wait(__lock);
}
}

生产者和消费者模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
#include<mutex>
#include<thread>
#include<condition_variable>
#include<queue>

std::queue<int> queue;
std::condition_variable conditionVariable;
std::mutex mux;

void productor(){
for (int i = 0; i < 10; ++i) {
std::unique_lock<std::mutex> u_lock(mux);
int num=queue.front();
queue.push(i);
//通知消费者来取任务
conditionVariable.notify_one();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
void resumer(){
while(1)
{
std::unique_lock<std::mutex> u_lock(mux);

if(queue.empty()){
//等待通知
conditionVariable.wait(u_lock,[](){
return !queue.empty();
});
}

queue.pop();
}

}