C++11 thread 及互斥锁、条件变量

启动的格式:
#include <thread>//包含头文件
void fucntion();//定义一个线程执行的函数
thread t1(fucntion);//线程启动这个函数
//一创建就自动运行,主线程非阻塞

void factorial(int n,char b,..);//带参数的函数,参数的个数顺延
thread t2(factorial,5,'a',..);//线程启动带参数的函数
t1.join(); //阻塞

线程一些控制函数:
Join() :让主线程等待 阻塞
t1.join();

Detach():非阻塞(默认)
t1.detach();//最好写上

Move() :转移、窃取
thread t2 = move(t1);
//线程无法赋值,只能被转移相当于换个名字,但转移后的t1无值

Ref() :线程传递参数传递的是引用,n为参数(需要互锁,存在数据竞争)
thread t1(fucntion,ref(n));

使用互斥同步线程:
假如多个线程同时争夺cout资源,则结果输出无序,这时就需要使用互斥对象mutex。注意可能会出现死锁。

#include <mutex>//包含头文件
mutex mut;//定义一个互斥变量
mut.lock();//上锁
cout << "我是通过主线程执行的" << i << endl;
mut.unlock();//解锁

mutex的封装 Lock_guard unique_lock:
lock_guard
把锁放到lock_guard中时,mutex自动上锁,lock_guard析构时,同时把mutex解锁
void share_print(string msg, int id)
{
lock_guard<mutex> guard(mut);
cout << msg << " id = " << id << endl;
}

unique_lock
第三种方式加锁:unique_lock 更有弹性
缺点:消耗更多系统资源

1 unique_lock<mutex> locker(m_mutex);//自动上锁
cout << str << i << endl;
//解锁
locker.unlock();
//。。。进行其他操作 更弹性

2 defer_lock表示不对mutex加锁,只管理mutex,此时mutex是没有加锁的
unique_lock<mutex> locker(m_mutex,defer_lock);
//本区间未上锁
locker.lock();
cout << str << i << endl;//上锁
//解锁
locker.unlock();
//。。。进行其他操作 更弹性

3 lock_gard 无法复制(=) 无法移动
unique_lock 可以被移动 mutex会被转移,原先的失效
unique_lock<mutex> lokcer = move(locker1);
缺点:消耗更多性能 unique_lock更有弹性,lock_gard性能更优 unique_lock内部持有mutex的状态:locked,unlocked。unique_lock比lock_guard占用空间和速度慢一些,因为其要维护mutex的状态。

死锁:
什么叫死锁?
线程A和B互相等待各自持有的资源释放,进入死循环。
死锁产生
例如:
//一个线程中
lock_guard<mutex> guard1(m_mutex2);//执行成功 mutex2成功上锁
lock_guard<mutex> guard(m_mutex1);//等待mutex1解锁
//另一个线程
lock_guard<mutex> guard1(m_mutex1);//执行成功 mutex1成功上锁
lock_guard<mutex> guard(m_mutex2);//等待mutex2解锁
//则有可能死锁
解决方案
1:只使用一个mutex
2:保证 locker顺序相同
//一个线程中(先执行)
lock_guard<mutex> guard1(m_mutex1);//执行成功 mutex1成功上锁
lock_guard<mutex> guard(m_mutex2);//等待mutex1解锁
//另一个线程
lock_guard<mutex> guard1(m_mutex1);//等待mutex1解锁
lock_guard<mutex> guard(m_mutex2);//等待mutex2解锁
3:使用lock()
std::lock会使用一种避免死锁的算法对多个待加锁对象进行lock操作,当待加锁的对象中有不可用对象时std::lock会阻塞当前线程知道所有对象都可用。
lock(m_mutex1, m_mutex2);
lock_guard<mutex> guard1(m_mutex2, adopt_lock);
lock_guard<mutex> guard(m_mutex, adopt_lock);
//adopt_lock相当于让lock()接手控制
4:清楚你写的代码,避免产生此问题

条件变量
std::condition_variable 
当std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了notification 函数来唤醒当前线程。

notify_one()  唤醒一个在等待线程
notify_all()唤醒所有等待的线程

condition_variable cond;
cond.wait(locker);
cond.notify_one();










  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值