网站建设多久中小企业解决方案
2026/4/10 19:56:17 网站建设 项目流程
网站建设多久,中小企业解决方案,网站建设 临沂,很长的网站域名怎么做短提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录std::mutex 与 std::lock 详解及使用指南一、std::mutex 详解1. 什么是 std::mutex2. std::mutex 的核心成员函数3. std::mutex 的基本使用#xff08;不推荐直接用…提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录std::mutex 与 std::lock 详解及使用指南一、std::mutex 详解1. 什么是 std::mutex2. std::mutex 的核心成员函数3. std::mutex 的基本使用不推荐直接用仅作示例示例1基础使用存在风险示例2直接使用的缺陷异常导致死锁4. 改进RAII 风格的锁管理推荐使用1std::lock_guard轻量级RAII锁推荐用于简单场景2std::unique_lock灵活的RAII锁推荐用于复杂场景二、std::lock 详解1. 什么是 std::lock2. std::lock 的核心特点3. std::lock 的使用场景死锁示例依次加锁导致4. std::lock 解决死锁推荐用法说明三、总结与注意事项1. 核心总结2. 关键注意事项3. 编译运行命令GCCstd::mutex与std::lock详解及使用指南std::mutex和std::lock是 C11 标准库中用于多线程同步的核心组件主要解决数据竞争和死锁问题。其中std::mutex是基础的互斥锁类型而std::lock是用于安全锁定多个互斥锁的函数模板二者常配合使用。一、std::mutex详解1. 什么是std::mutexstd::mutex互斥量Mutual Exclusion是 C 标准库提供的基础互斥锁属于mutex头文件。它的核心作用是保护临界区多个线程同时访问的共享资源代码段确保同一时间只有一个线程能进入临界区从而避免数据竞争未定义行为。std::mutex是非递归锁也叫非重入锁即同一个线程不能对同一个std::mutex多次调用lock()否则会导致死锁。2.std::mutex的核心成员函数成员函数功能说明lock()加锁如果锁已被其他线程占用当前线程会阻塞直到获得锁。try_lock()尝试加锁成功返回true失败锁被占用返回false不会阻塞。unlock()解锁释放锁必须由持有锁的线程调用否则行为未定义。native_handle()获取底层操作系统的锁句柄用于高级操作跨平台兼容性差。3.std::mutex的基本使用不推荐直接用仅作示例直接调用lock()和unlock()是最基础的用法但存在严重缺陷如忘记解锁、异常导致解锁失败仅用于理解原理。示例1基础使用存在风险#includeiostream#includethread#includemutex#includevector// 共享资源intg_count0;// 互斥锁保护g_countstd::mutex g_mutex;// 累加函数voidincrement(inttimes){for(inti0;itimes;i){// 加锁进入临界区g_mutex.lock();// 临界区操作共享资源g_count;// 解锁退出临界区g_mutex.unlock();// 模拟耗时操作锁外执行减少阻塞std::this_thread::sleep_for(std::chrono::nanoseconds(1));}}intmain(){constintthread_num5;constinttimes_per_thread1000;std::vectorstd::threadthreads;// 创建线程for(inti0;ithread_num;i){threads.emplace_back(increment,times_per_thread);}// 等待线程结束for(autot:threads){t.join();}std::cout最终count值g_countstd::endl;// 正确输出5000return0;}示例2直接使用的缺陷异常导致死锁如果临界区中抛出异常unlock()不会被执行锁会被永久占用导致其他线程死锁voidincrementWithException(inttimes){for(inti0;itimes;i){g_mutex.lock();// 模拟异常比如除以0if(i500){throwstd::runtime_error(意外异常);// 异常抛出unlock()不会执行}g_count;g_mutex.unlock();// 永远执行不到}}4. 改进RAII 风格的锁管理推荐使用为了解决手动加锁/解锁的缺陷C 提供了RAII资源获取即初始化风格的锁管理类它们会在构造时自动加锁析构时自动解锁即使发生异常从根本上避免死锁。1std::lock_guard轻量级RAII锁推荐用于简单场景std::lock_guard是最简单的 RAII 锁功能单一构造加锁析构解锁不支持手动控制锁的生命周期。示例用std::lock_guard修复异常问题#includeiostream#includethread#includemutex#includevector#includestdexceptintg_count0;std::mutex g_mutex;voidincrementSafe(inttimes){for(inti0;itimes;i){// RAII构造时加锁析构时解锁即使异常也会解锁std::lock_guardstd::mutexlock(g_mutex);// 模拟异常if(i500){// 异常抛出时lock的析构函数会被调用自动解锁throwstd::runtime_error(意外异常);}g_count;}}intmain(){constintthread_num5;constinttimes_per_thread1000;std::vectorstd::threadthreads;try{for(inti0;ithread_num;i){threads.emplace_back(incrementSafe,times_per_thread);}for(autot:threads){t.join();}}catch(conststd::exceptione){std::cout捕获异常e.what()std::endl;}std::cout最终count值g_countstd::endl;return0;}2std::unique_lock灵活的RAII锁推荐用于复杂场景std::unique_lock比std::lock_guard更灵活支持手动加锁/解锁lock()/unlock()延迟加锁构造时不加锁后续手动调用lock()尝试加锁try_lock()超时加锁try_lock_for()/try_lock_until()配合条件变量std::condition_variable使用转移锁的所有权支持移动语义不可复制。示例std::unique_lock的灵活使用#includeiostream#includethread#includemutex#includevectorintg_count0;std::mutex g_mutex;voidincrementFlexible(inttimes){for(inti0;itimes;i){// 延迟加锁构造时不加锁后续手动加锁std::unique_lockstd::mutexlock(g_mutex,std::defer_lock);// 手动加锁也可以用try_lock()尝试加锁lock.lock();g_count;// 手动解锁可选析构时会自动解锁这里提前解锁以减少阻塞lock.unlock();// 锁已释放其他线程可进入临界区std::this_thread::sleep_for(std::chrono::nanoseconds(1));}}intmain(){constintthread_num5;constinttimes_per_thread1000;std::vectorstd::threadthreads;for(inti0;ithread_num;i){threads.emplace_back(incrementFlexible,times_per_thread);}for(autot:threads){t.join();}std::cout最终count值g_countstd::endl;return0;}二、std::lock详解1. 什么是std::lockstd::lock是 C11 提供的函数模板位于mutex头文件不是锁类型。它的核心作用是同时锁定多个互斥锁并采用避免死锁的算法如按互斥锁的内存地址顺序加锁确保要么所有锁都被成功锁定要么一个都不锁定如果其中一个锁被占用会释放已锁定的锁等待后重试。2.std::lock的核心特点接收多个互斥锁的引用作为参数至少两个原子操作要么全部锁定要么全部不锁定避免死锁内部实现了死锁避免逻辑如按地址排序加锁不管理锁的生命周期锁定后需要手动解锁或配合 RAII 类的std::adopt_lock参数。3.std::lock的使用场景当一个线程需要同时访问多个共享资源对应多个互斥锁时直接依次加锁可能导致死锁此时用std::lock可以安全锁定多个锁。死锁示例依次加锁导致两个线程同时尝试锁定两个互斥锁但顺序相反导致互相等待#includeiostream#includethread#includemutexstd::mutex m1,m2;// 线程1先锁m1再锁m2voidthread1Func(){for(inti0;i1000;i){m1.lock();m2.lock();// 可能被线程2的m2.lock()阻塞此时线程1持有m1线程2持有m2死锁// 临界区操作共享资源std::cout线程1执行临界区std::endl;m2.unlock();m1.unlock();}}// 线程2先锁m2再锁m1voidthread2Func(){for(inti0;i1000;i){m2.lock();m1.lock();// 可能被线程1的m1.lock()阻塞导致死锁// 临界区操作共享资源std::cout线程2执行临界区std::endl;m1.unlock();m2.unlock();}}intmain(){std::threadt1(thread1Func);std::threadt2(thread2Func);t1.join();t2.join();return0;}上述代码运行后大概率会出现死锁程序卡死。4.std::lock解决死锁推荐用法使用std::lock同时锁定多个互斥锁配合std::unique_lock的std::adopt_lock参数表示锁已被手动锁定由unique_lock接管生命周期#includeiostream#includethread#includemutexstd::mutex m1,m2;// 线程1用std::lock同时锁m1和m2voidthread1Func(){for(inti0;i1000;i){// 步骤1创建unique_lock延迟加锁std::unique_lockstd::mutexlock1(m1,std::defer_lock);std::unique_lockstd::mutexlock2(m2,std::defer_lock);// 步骤2同时锁定m1和m2避免死锁std::lock(lock1,lock2);// 也可以写std::lock(m1, m2)// 临界区操作共享资源std::cout线程1执行临界区std::endl;// 步骤3析构时自动解锁无需手动unlock}}// 线程2同样用std::lock同时锁m1和m2顺序无关voidthread2Func(){for(inti0;i1000;i){std::unique_lockstd::mutexlock1(m1,std::defer_lock);std::unique_lockstd::mutexlock2(m2,std::defer_lock);std::lock(lock2,lock1);// 顺序与线程1相反仍不会死锁// 临界区操作共享资源std::cout线程2执行临界区std::endl;}}intmain(){std::threadt1(thread1Func);std::threadt2(thread2Func);t1.join();t2.join();return0;}说明std::defer_lock表示unique_lock构造时不自动加锁std::lock(lock1, lock2)同时锁定两个unique_lock关联的互斥锁也可以直接传m1, m2std::adopt_lock可选如果直接调用std::lock(m1, m2)手动锁定则需要用std::unique_lockstd::mutex lock1(m1, std::adopt_lock)表示接管已锁定的锁。三、总结与注意事项1. 核心总结组件定位核心用途推荐场景std::mutex基础互斥锁类型保护单个临界区实现基本同步作为底层锁配合RAII类使用std::lock_guard轻量级RAII锁简单临界区的自动加锁/解锁无复杂逻辑的临界区优先使用std::unique_lock灵活的RAII锁复杂场景延迟加锁、超时、条件变量需手动控制锁生命周期的场景std::lock多锁同步函数模板同时锁定多个互斥锁避免死锁需访问多个共享资源多个mutex的场景2. 关键注意事项避免直接使用std::mutex的lock()/unlock()优先使用std::lock_guard或std::unique_lock利用RAII避免死锁。std::mutex是非递归锁同一线程不能多次锁定同一个std::mutex会死锁如果需要递归锁使用std::recursive_mutex但递归锁易导致逻辑混乱尽量避免使用。临界区尽可能小只在必要的代码段加锁减少线程阻塞时间提升并发性能。多锁场景必须用std::lock不要手动依次加锁否则极易导致死锁。编译时链接线程库使用C多线程时GCC/Clang需加-pthread参数MSVC需启用线程支持。3. 编译运行命令GCC# 编译示例代码g -stdc11 mutex_lock_demo.cpp -o mutex_lock_demo -pthread# 运行./mutex_lock_demo

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询