博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vins-mono使用的多线程代码解读
阅读量:518 次
发布时间: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/

你可能感兴趣的文章