博客
关于我
vins-mono使用的多线程代码解读
阅读量:519 次
发布时间:2019-03-07

本文共 3641 字,大约阅读时间需要 12 分钟。

在读vins-mono的代码时,对于多线程的处理还是比较陌生,于是集中学习一下。学习内容包括

1.lock_guard.

2. unique lock

3.condition variable

lock_guard

功能介绍

首先,使用它的前提是,你要有一个mutex object。

场景:

使用一个mutex直到out of scope

0. It is very light weight wrapper for owning mutex on scoped basis.

1. It acquries mutex lock the moment you create the object of lock guard

2. It automatically removes the lock while goes out of scope.

3. You can not explicitly unlock the lock_guard

4. you can not copy lock_guard.

talk is cheap, I show the code

#include 
#include
#include
using namespace std;std::mutex m1;int buffer = 0;void task(const char* threadNumber, int loopFor) { //std::lock_guard
lock(m1); for(int i=0; i

上述这段多线程代码,没有线程锁,那么结果可想而出,输出的结果会存在混乱。

解决方案1:使用lock和unlock可以解决问题

解决方案2: 根据观察,被lock/unlock的函数在执行结束后就没了,线程锁的需要时间是从lock到运行结束。。。而如果去掉unlock的话,程序也是无法自动切换到另一个线程。

我们期待的流程是,线程进入mutex,线程结束,直接切换到下一个线程。

而lock_guard可以实现这个过程,取代lock和unlock的过程。

在vins-mono的代码里,在imu调用的scope中,lock guard被调用,那么它会在这个区间一直启动。不被中断,直到publish。

 

Unique Lock

The class unqiue_lock is a mutex ownership wrapper.

automaticllay call the lock on the mutex.

It allow:

A. can have different locking strategies.

b. time-constrained attempts at locking. (try_lock_for, try_lock_until)

c. recursive locking

d. transfer of lock ownership

e. condition variable.

unique lock的作用和lock_guard 相似。两者的区别,这篇文章的解释很好。

总结一下区别

1. unique_lock可以使用unlock,而lock_guard不可以

2. 我认为是更重要的一点--它可以配合condition variable使用

这基本解释了在代码里使用unique_lock的原因,因为我们想要wait和条件变量。

condition variable

我们想根据条件判断选择运行哪个线程。

 

使用场景:

 线程1和线程2, 1在运行,2在sleep,现在1想叫醒2(使用notify_one 或者notify_all),叫醒一个人或者其他所有人,同时,有一个条件需要被满足。

举例介绍:

假设有两个线程,分别用来取钱存钱。

那么,取钱的基础是有钱,所以设计程序的时候,我们想判断有没有钱,在进行存取钱,或者说,如果没钱,不让他取钱,所以,首先,你需要lock 了withdrawmoney这个线程。然后,啥时候能取钱呢?在这个程序里,你需要等待balance不是0,如果balance=0,  那么你就需要release the lock。换句话说,balance=0的时候,他在这个线程就会一直等待(存钱)。。。把ul作为wait的参数,就是利用wait来release mutex。

总之,通过conditrion的思路,你可以选择让一个thread有更高的优先级,或者说一直首先运行。

然后,在wait的时候,在addMoney这个线程,通过lock guard锁上了,在最后一步,通过notify one,我提醒cv不用接着等,可以再考虑一下了。

 

源码如下:

/*conditon variable in c++ threadingIMPORTANT POINT: cv are used for two purposesA. Notify other threadsB. Waiting for some condicitons1. Condition variable allows running threads to wait on some conditions and onve those conditions are met, the waiting thread is notified using:    a. notify_one();    b. notify_all();2. You need mutec to use condition variable.3. If some threads want to wait on some condition then it has to do these things    a. Acquire the mutec lock using std::unique_lock
lock(m); b. Exexute wait, wait_for, or wait_until. The wait operations automically release the mutex and suspend the execution of the thread c. When the condition variable is notified, the thread is awakened, and the mutex is automically reacquired. The thread should then check the condition and resume waiting if the wake up was spurious. Note 1; Condition variables are used to synchronize two or more threads.2 2: Best use case of condition variables is Producer/Consumer problem.*/#include
#include
#include
#include
using namespace std;std::condition_variable cv;std::mutex m;long balance = 0;//add money will always start firstvoid addMoney(int money) { std::lock_guard
lg(m);//haveto work to the end of the scope balance+=money; cout<<"Amount added current balance: "<
<
ul(m);//acquire the lock cv.wait(ul/*unique lock*/,[]{return (balance!=0)?true:false;});//if true , go further, false, release the lock and wait if (balance>=money) { balance -=money; cout<<"Amount deducted: "<
<

附上wait的api

 

转载地址:http://nvhjz.baihongyu.com/

你可能感兴趣的文章
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_插入时如果目标表中已存在该数据则自动改为更新数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0058
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_更新时如果目标表中不存在记录就改为插入数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0059
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0_Postgresql和Mysql同时指定库_指定多表_全量同步到Mysql数据库以及Hbase数据库中---大数据之Nifi工作笔记0060
查看>>
NIFI1.21.0最新版本安装_连接phoenix_单机版_Https登录_什么都没改换了最新版本的NIFI可以连接了_气人_实现插入数据到Hbase_实际操作---大数据之Nifi工作笔记0050
查看>>
NIFI1.21.0最新版本安装_配置使用HTTP登录_默认是用HTTPS登录的_Https登录需要输入用户名密码_HTTP不需要---大数据之Nifi工作笔记0051
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增加修改实时同步_使用JsonPath及自定义Python脚本_03---大数据之Nifi工作笔记0055
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_插入修改删除增量数据实时同步_通过分页解决变更记录过大问题_01----大数据之Nifi工作笔记0053
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表或全表增量同步_实现指定整库同步_或指定数据表同步配置_04---大数据之Nifi工作笔记0056
查看>>
NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现update数据实时同步_实际操作05---大数据之Nifi工作笔记0044
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_生成插入Sql语句_实际操作02---大数据之Nifi工作笔记0041
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_不带分页处理_01_QueryDatabaseTable获取数据_原0036---大数据之Nifi工作笔记0064
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
查看>>