欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > C++学习笔记(20)

C++学习笔记(20)

2025/5/16 21:16:50 来源:https://blog.csdn.net/qq_60098634/article/details/142219144  浏览:    关键词:C++学习笔记(20)

六、线程安全
示例:
#include <iostream>
#include <thread> // 线程类头文件。
using namespace std;
int aa = 0; // 定义全局变量。
// 普通函数,把全局变量 aa 加 1000000 次。
void func() {
for (int ii = 1; ii <= 1000000; ii++)
aa++;
}
int main()
{
// 用普通函数创建线程。
thread t1(func); // 创建线程 t1,把全局变量 aa 加 1000000 次。
thread t2(func); // 创建线程 t2,把全局变量 aa 加 1000000 次。
t1.join(); // 回收线程 t1 的资源。
t2.join(); // 回收线程 t2 的资源。
cout << "aa=" << aa << endl; // 显示全局变量 aa 的值。
}
242、互斥锁
C++11 提供了四种互斥锁:
 mutex:互斥锁。
 timed_mutex:带超时机制的互斥锁。
 recursive_mutex:递归互斥锁。
 recursive_timed_mutex:带超时机制的递归互斥锁。
包含头文件:#include <mutex> 一、mutex 类
1)加锁 lock()
互斥锁有锁定和未锁定两种状态。
如果互斥锁是未锁定状态,调用 lock()成员函数的线程会得到互斥锁的所有权,并将其上锁。
如果互斥锁是锁定状态,调用 lock()成员函数的线程就会阻塞等待,直到互斥锁变成未锁定状态。
2)解锁 unlock()
只有持有锁的线程才能解锁。
3)尝试加锁 try_lock()
如果互斥锁是未锁定状态,则加锁成功,函数返回 true。
如果互斥锁是锁定状态,则加锁失败,函数立即返回 false。(线程不会阻塞等待)
示例:
#include <iostream>
#include <thread> // 线程类头文件。
#include <mutex> // 互斥锁类的头文件。
using namespace std;
mutex mtx; // 创建互斥锁,保护共享资源 cout 对象。
// 普通函数。
void func(int bh, const string& str) {
for (int ii = 1; ii <= 10; ii++)
{
mtx.lock(); // 申请加锁。
cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
mtx.unlock(); // 解锁。
this_thread::sleep_for(chrono::seconds(1)); // 休眠 1 秒。
}
}
int main()
{
// 用普通函数创建线程。
thread t1(func, 1, "我是一只傻傻鸟。");
thread t2(func, 2, "我是一只傻傻鸟。");
thread t3(func, 3, "我是一只傻傻鸟。");
thread t4(func, 4, "我是一只傻傻鸟。");
thread t5(func, 5, "我是一只傻傻鸟。");
t1.join(); // 回收线程 t1 的资源。
t2.join(); // 回收线程 t2 的资源。
t3.join(); // 回收线程 t3 的资源。
t4.join(); // 回收线程 t4 的资源。
t5.join(); // 回收线程 t5 的资源。
}
二、timed_mutex 类
增加了两个成员函数:
bool try_lock_for(时间长度);
bool try_lock_until(时间点);
三、recursive_mutex 类
递归互斥锁允许同一线程多次获得互斥锁,可以解决同一线程多次加锁造成的死锁问题。
示例:
#include <iostream>
#include <mutex> // 互斥锁类的头文件。
using namespace std;
class AA
{
recursive_mutex m_mutex;
public:
void func1() {
m_mutex.lock();
cout << "调用了 func1()\n";
m_mutex.unlock();
}
void func2() {
m_mutex.lock();
cout << "调用了 func2()\n";
func1();
m_mutex.unlock();
}
};
int main()
{
AA aa;
//aa.func1();
aa.func2();
}
四、lock_guard 类
lock_guard 是模板类,可以简化互斥锁的使用,也更安全。
lock_guard 的定义如下:
template<class Mutex>
class lock_guard
{
explicit lock_guard(Mutex& mtx);
}
lock_guard 在构造函数中加锁,在析构函数中解锁。
lock_guard 采用了 RAII 思想(在类构造函数中分配资源,在析构函数中释放资源,保证资源在离开
作用域时自动释放)。
 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词