1、参考
c++11中的lock_guard和unique_lock使用浅析
2、相关代码
方式一:
std::shared_ptr<cyber::Reader<planning::PadMessage>> pad_msg_reader_;
pad_msg_reader_ = node->CreateReader<PadMessage>(
config_.topic_config().planning_pad_topic(),
[this](const std::shared_ptr<PadMessage>& pad_msg) {
AINFO << "Received pad data: run pad callback.";
std::lock_guard<std::mutex> lock(mutex_);
pad_msg_.CopyFrom(*pad_msg);
AINFO<<"pad_msg_.action is:"<<pad_msg_.action();
});
.h文件中增加成员变量:
private:
std::mutex mutex_;
planning::PadMessage pad_msg_;
方式二:
std::mutex mutex_;
planning::PadMessage pad_msg_;
std::shared_ptr<cyber::Reader<planning::PadMessage>> pad_msg_reader_;
pad_msg_reader_ = node->CreateReader<PadMessage>(
config_.topic_config().planning_pad_topic(),
[&mutex_,&pad_msg_,this](const std::shared_ptr<PadMessage>& pad_msg) {
AINFO << "Received pad data: run pad callback.";
std::lock_guard<std::mutex> lock(mutex_);
pad_msg_.CopyFrom(*pad_msg);
AINFO<<"pad_msg_.action is:"<<pad_msg_.action();
});
CreateReader 函数体代码如下:
template <typename MessageT>
auto Node::CreateReader(const ReaderConfig& config,
const CallbackFunc<MessageT>& reader_func)
-> std::shared_ptr<cyber::Reader<MessageT>> {
std::lock_guard<std::mutex> lg(readers_mutex_);
if (readers_.find(config.channel_name) != readers_.end()) {
AWARN << "Failed to create reader: reader with the same channel already "
"exists.";
return nullptr;
}
auto reader =
node_channel_impl_->template CreateReader<MessageT>(config, reader_func);
if (reader != nullptr) {
readers_.emplace(std::make_pair(config.channel_name, reader));
}
return reader;
}
3、相关知识点
多线程锁的使用: 锁用来在多线程访问同一个资源时防止数据竞险,保证数据的一致性访问。
多线程本来就是为了提高效率和响应速度,但锁的使用又限制了多线程的并行执行,这会降低效率,但为了保证数据正确,不得不使用锁,它们就是这样纠缠。
作为效率优先的c++开发人员,很多人谈锁色变。
虽然有很多的无锁技术应用到项目中来,但是还是很有必要对锁的技术有一个基础的理解。本文主要讨论c++11中的两种锁:lock_guard 和 unique_lock。
结合锁进行线程间同步的条件变量使用,请参考条件变量condition variable 。
参考示例:
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>
std::mutex my_lock;
void add(int &num, int &sum){
while(true){
std::lock_guard<std::mutex> lock(my_lock);
if (num < 100){
num += 1;
sum += num;
}
else {
break;
}
}
}
int main(){
int sum = 0;
int num = 0;
std::vector<std::thread> ver;
for(int i = 0; i < 20; ++i){
std::thread t = std::thread(add, std::ref(num), std::ref(sum));
ver.emplace_back(std::move(t));
}
std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join));
std::cout << sum << std::endl;
}
|