当前位置: 首页 > wzjs >正文

好看的网站案例郴州网站seo

好看的网站案例,郴州网站seo,帮别人做网站后期维护,做英国代购的公司网站【学习笔记】锁死锁gdb调试死锁 一、互斥锁&#xff08;std::mutex&#xff09; 最基本的锁类型&#xff0c;提供排他性访问&#xff0c;同一时间仅允许一个线程持有锁。 #include <iostream> #include <mutex> #include <thread>std::mutex mtx; // 全局…

【学习笔记】锁+死锁+gdb调试死锁

一、互斥锁(std::mutex)

最基本的锁类型,提供排他性访问,同一时间仅允许一个线程持有锁。

#include <iostream>
#include <mutex>
#include <thread>std::mutex mtx;  // 全局互斥锁
int shared_data = 0;  // 共享资源void increment() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(mtx);  // 自动加锁++shared_data;  // 临界区}  // 作用域结束,自动解锁
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Final value: " << shared_data << std::endl;  // 输出 200000return 0;
}

二、读写锁(std::shared_mutex)

多读单写锁,允许多个线程同时读,但写时独占。适用于读多写少的场景。

#include <shared_mutex>  // C++17 及以上
#include <thread>
#include <vector>
#include <iostream>std::shared_mutex rw_mutex;
int shared_data = 0;// 读操作(允许多线程并发)
void reader(int id) {for (int i = 0; i < 1000; ++i) {std::shared_lock<std::shared_mutex> lock(rw_mutex);  // 共享锁(读锁)std::cout << "Reader " << id << ": " << shared_data << std::endl;}
}// 写操作(独占)
void writer() {for (int i = 0; i < 10; ++i) {std::unique_lock<std::shared_mutex> lock(rw_mutex);  // 独占锁(写锁)++shared_data;std::cout << "Writer updated: " << shared_data << std::endl;}
}int main() {std::vector<std::thread> readers;for (int i = 0; i < 5; ++i) {readers.emplace_back(reader, i);}std::thread w(writer);for (auto& t : readers) t.join();w.join();return 0;
}

std::shared_lock:用于读操作,允许多个线程同时持有。

std::unique_lock:用于写操作,独占资源,同一时间仅允许一个线程持有。

三、高级锁管理(std::unique_lock)

std::unique_lock 是一种比 std::lock_guard (自动加锁)更灵活的锁管理工具,主要用于需要手动控制锁的生命周期的场景。

比如说想在某一处执行的地方,某一个变量的赋值之前加锁,赋值完毕之后解锁,比较灵活,但是需要注意解锁。

#include <mutex>
#include <thread>std::mutex mtx;void worker() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 构造时不加锁// 执行无需锁的操作...lock.lock();  // 手动加锁// 临界区lock.unlock();  // 手动解锁// 执行其他无需锁的操作...
}

std::unique_lock 在析构时会自动解锁,因此忘记手动解锁不会导致死锁,但可能导致锁持有时间过长,降低并发性能。

四、死锁

https://www.51cto.com/article/623760.html

1、死锁条件

死锁的四个条件:

​ ● 不可抢占(no preemption):系统资源不能被强制从一个进程(线程)中退出,已经获得的资源在未使用完之前不能被抢占。

​ ● 占有并等待(hold and wait):一个进程(线程)因请求资源阻塞时,对已获得的资源保持不放。

​ ● 互斥(mutual exclusion):资源只能同时分配给一个进程(线程),无法多个进程(线程)共享。

​ ● 循环等待(circular waiting):一系列进程(线程)互相持有其他进程(线程)所需要的资源。

只有同时满足以上四个条件,才会产生死锁,想要消除死锁只需要破坏其中任意一个条件即可。

using std::cout; std::mutex mutex1; 
std::mutex mutex2; 
std::mutex mutex3; void FuncA() { std::lock_guard<std::mutex> guard1(mutex1);  // 获取mutex1std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard2(mutex2);  // 获取mutex2(如果已被B持有,则阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} void FuncB() { std::lock_guard<std::mutex> guard2(mutex2);  // 获取mutex2std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard3(mutex3);  // 获取mutex3(如果已被C持有,则阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} void FuncC() { std::lock_guard<std::mutex> guard3(mutex3);  // 获取mutex3std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒std::lock_guard<std::mutex> guard1(mutex1);  // 获取mutex1(如果已被A持有,则阻塞)std::this_thread::sleep_for(std::chrono::seconds(1));  // 休眠1秒
} int main() { std::thread A(FuncA); std::thread B(FuncB); std::thread C(FuncC); std::this_thread::sleep_for(std::chrono::seconds(5)); // 尝试回收子线程if (A.joinable()) A.join(); if (B.joinable()) B.join(); if (C.joinable()) C.join(); cout << "hello\n";  // 永远不会执行   return 0; 
} 

2、gdb调试死锁

直接gdb+可执行程序,应该会什么都不打印,一直鼠标跳动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

线程 1 (LWP 3097)

  • 角色:主线程(从main函数启动的线程)。
  • 状态:阻塞在futex系统调用,等待某个条件(可能是等待子线程结束)。
  • 关键点expected=3100表明它在等待线程 ID 为 3100 的子线程(即 LWP 3100)。

线程 2 (LWP 3100)

  • 角色:执行FuncA()的线程(根据锁地址匹配)。
  • 状态:阻塞在mutex2(地址0x55555555a1a0)上。
  • 关键点expected=2表示它期望锁的状态为 2(可能是 “已锁定”),但当前锁被其他线程持有。

线程 3 (LWP 3101)

  • 角色:执行FuncB()的线程。
  • 状态:阻塞在mutex3(地址0x55555555a1e0)上。

线程 4 (LWP 3102)

  • 角色:执行FuncC()的线程。

  • 状态:阻塞在mutex1(地址0x55555555a160)上。

  • 等待的锁:线程 2 在等待mutex2,线程 3 在等待mutex3,线程 4 在等待mutex1

  • 已持有的锁:需结合源代码逻辑推断(例如线程 2 已持有mutex1,因为它在等待mutex2之前获取了mutex1)。

死锁原因分析:

结合你的原始代码:

  1. 线程 2(FuncA) 已持有mutex1,正在等待mutex2
  2. 线程 3(FuncB) 已持有mutex2,正在等待mutex3
  3. 线程 4(FuncC) 已持有mutex3,正在等待mutex1

形成循环依赖链:线程 2 → 线程 3 → 线程 4 → 线程 2,导致死锁。

在这里插入图片描述

死锁原因分析:

结合你的原始代码:

  1. 线程 2(FuncA) 已持有mutex1,正在等待mutex2
  2. 线程 3(FuncB) 已持有mutex2,正在等待mutex3
  3. 线程 4(FuncC) 已持有mutex3,正在等待mutex1

形成循环依赖链:线程 2 → 线程 3 → 线程 4 → 线程 2,导致死锁。

(gdb) thread apply all bt 也可以运行以下命令查看所有线程的堆栈

http://www.dtcms.com/wzjs/18170.html

相关文章:

  • 本地拖拽网站建设网络营销的分类
  • 深圳企业网站seo网站seo优化推广外包
  • 如何制作手机购物网站郑州免费做网站
  • 关于网站开发的商业计划书百度客服在哪里找
  • phpcms怎么做网站手机地图app下载安装
  • 学校网站建设培训方案苏州百度推广
  • 手机特殊网站怎么做属于自己的网站
  • 网站上线前要做哪些准备网络竞价
  • 济南网站制作价格商铺营销推广方案
  • 设计网站的元素推广新产品最好的方法
  • 中山市城乡和住房建设局网站长沙排名优化公司
  • 海口手机版网站建设专业关键词排名优化软件
  • 深圳做微信商城网站建设it行业培训机构一般多少钱
  • 多语言外贸企业网站源码百度网站排名查询
  • 做网站维护师傅带要学多久搜索引擎推广简称
  • 政府 社区网站建设营销方案策划书
  • 杭州制作网站企业关键词的选取原则
  • 捕鱼游戏在哪做网站seo技术软件
  • 国外自助建站系统百度推广费用一年多少钱
  • 四川做网站公司5151app是交友软件么
  • 做qq主题的网站微信公众号怎么开通
  • 大网站制作公司佛山百度推广电话
  • wordpress如何去掉分类里面的大字南宁网站优化
  • 如何把省市县三级下拉菜单弄到网站的在线表单内外贸建站
  • 高清视频服务器内存seo关键词推广话术
  • 郑州富士康有多少人员工seo教程之关键词是什么
  • 泰州高端网站建设搜索图片
  • 徐州网站建设公司排名seo研究中心
  • 帮别做网站沈阳cms模板建站
  • 永嘉专业网站设计公司网站自助建站系统