多线程-数据共享问题
2021-05-05 16:30
标签:sage 目的 back 提取 class ESS 分支语句 main pause 一、基本概念 1、互斥量(mutex) 互斥量:是个类对象(可以理解为一把锁),多个线程尝试用lock()成员函数来加锁这把锁,只有一个线程能锁定成功(成功的标志是lock()函数能够返回,返回不了说明没有锁成功) 2、死锁 死锁:一般是两个或两个以上的互斥量,在两个或多个地方上锁的顺序不一致导致的互相等待的情况 死锁解决方法:保证每个地方,互斥量上锁的顺序一致 二、样例 1、多线程加锁的例子 2、lock_guard 3、std::lock 4、结合std::lock() 和lock_guard 多线程-数据共享问题 标签:sage 目的 back 提取 class ESS 分支语句 main pause 原文地址:https://www.cnblogs.com/zhiminzeng/p/13192159.htmlclass MyClass{ // 模拟给一个消息队列发消息和处理消息
public:
void WriteMessage() // 模拟发消息,也就是往消息队列中写
{
for (int i = 0; i 10000; ++i)
{
cout "插入一个元素:" endl;
m_mutex.lock(); // lock() 与 unlock() 要成对使用
m_messages.push_back(i);
m_mutex.unlock();
}
}
//void ReadMessage() // 模拟处理消息队列中的消息,从中读,也删除
//{
// for (int i = 0; i // {
// if (!m_messages.empty()) // 用到共享数据m_messages 的地方都要加锁
// {
// int i = m_messages.front(); // 用到共享数据m_messages 的地方都要加锁
// cout // 此处不需要加锁,只加锁需要加锁的部分,提高程序效率
// m_messages.pop_front(); // 用到共享数据m_messages 的地方都要加锁
// }
// else
// {
// cout // }
// }
//}
// 上面的函数优化后的结果
// 把需要加锁的代码专门提取出来
// 只对需要加锁的代码加锁,操作共享数据的部分
bool IsMessagesListEmpty(int& iCount)
{
m_mutex.lock();
if(!m_messages.empty())
{
iCount = m_messages.front();
m_messages.pop_front();
m_mutex.unlock(); // 每条分支语句都要unlock
return true;
}
m_mutex.unlock(); // 每条分支语句都要unlock
return false;
}
void ReadMessage() // 模拟处理消息队列中的消息,从中读,也删除
{
int iCount = 0;
for (int i = 0; i 10000; ++i)
{
if (IsMessagesListEmpty(i))
{
cout "读取的数据为:" endl;
}
else
{
cout "目前消息队列为空" endl;
}
}
}
private:
listint> m_messages; // 模拟消息队列
mutex m_mutex; // 创建一个互斥量成员对象
};
int main()
{
MyClass ele;
std::thread writeThread(&MyClass::WriteMessage, &ele); //
std::thread readThread(&MyClass::ReadMessage, &ele); //
readThread.join();
writeThread.join();
cout "主线程" endl;
system("pause");
return 0;
}
//std::lock_guard 相当于lock和unlock
std::lock_guard<:mutex> myLockGuard(m_mutex);
// myLockGuard构造的时候执行mutex::lock
// myLockGuard析构的时候执行mutex::unlock
// 可以通过加 {} 来控制lock_guard 的生存周期,从而达到随时加锁,随时解锁的目的
// 解决死锁的方法,保证上锁的顺序一致
// 也可以用std::lock() 来对多个锁进行加锁
// std::lock() 可以同时锁住两个或两个以上的互斥量
// 它不存在在多线程中,因为锁的顺序问题,而导致的死锁问题
// 要么其中的互斥量都锁住,要么都没锁住,不会锁住其中一个,而去等另外一个
// 也就是说,如果其中有一个锁已经被锁住了,它需要等所有的锁都能上锁的状态,才能加锁,继续往下执行
// 示例:
std::lock(m_mutex1, m_mutex2) // 上锁一起上
m_mutex1.unlock(); // 解锁还是需要自己解锁
m_mutex2.unlock();
// 结合lock_guard 和 std::lock 达到不需要手动unlock() 的效果
std::lock(m_mutex1, m_mutex2)
std::lock_guard<:mutex> myLockGuard(m_mutex1, std::adopt_lock);
std::lock_guard<:mutex> myLockGuard(m_mutex2, std::adopt_lock);
// std::adopt_lock 的作用是让 lock_guard 在构造的时候,不执行lock()
// 因为在std::lock()中已经执行了lock()
上一篇:递归--迷宫问题(Java)
下一篇:jQuery - 删除元素