西安商城网站计算机软件开发工资高吗
2026/2/14 19:07:00 网站建设 项目流程
西安商城网站,计算机软件开发工资高吗,常用的搜索引擎网站,北京市建设网站首页提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录先明确核心前提一、两种写法的执行流程拆解1. incrementManual#xff08;try 包裹整个 for 循环#xff09;2. incrementGuard#xff08;try 包裹单次循环迭代文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录先明确核心前提一、两种写法的执行流程拆解1. incrementManualtry 包裹整个 for 循环2. incrementGuardtry 包裹单次循环迭代二、结果差异的核心原因三、关键补充lock_guard 的安全性不受 try 位置影响总结#includeiostream#includethread#includemutex#includevector#includestdexcept#includechronointg_count0;std::mutex g_mutex;voidincrementManualGood(inttimes){try{for(inti0;itimes;i){g_mutex.lock();if(i500){std::cout手动加锁线程触发异常unlock() 将无法执行\n;throwstd::runtime_error(手动加锁临界区异常);}g_count;g_mutex.unlock();}}catch(conststd::exceptione){std::cout手动加锁线程捕获异常e.what()\n;g_mutex.unlock();}}voidincrementManualBad(inttimes){for(inti0;itimes;i){try{g_mutex.lock();if(i500){throwstd::runtime_error(手动加锁临界区异常);}g_count;g_mutex.unlock();// 正常路径解锁}catch(conststd::exceptione){std::cout手动加锁线程捕获异常e.what()\n;g_mutex.unlock();// 异常路径解锁}}}voidincrementGuardGood(inttimes){try{for(inti0;itimes;i){std::lock_guardstd::mutexlock(g_mutex);if(i500){throwstd::runtime_error(lock_guard临界区异常);}g_count;}}catch(conststd::exceptione){std::lock_guardstd::mutexlock(g_mutex);// 加锁保证输出不乱码std::coutlock_guard线程捕获异常e.what()\n;}}voidincrementGuardBad(inttimes){for(inti0;itimes;i){try{std::lock_guardstd::mutexlock(g_mutex);if(i500){throwstd::runtime_error(lock_guard临界区异常);}g_count;}catch(conststd::exceptione){std::lock_guardstd::mutexlock(g_mutex);// 加锁保证输出不乱码std::coutlock_guard线程捕获异常e.what()\n;}}}intmain(){constintthread_num5;constinttimes_per_thread1000;std::vectorstd::threadthreads;std::cout 测试手动加锁未手动解锁异常\n;g_count0;// 重置计数for(inti0;ithread_num;i){threads.emplace_back(incrementGuardBad,times_per_thread);}for(autot:threads){if(t.joinable()){t.join();}}std::cout手动加锁最终count值g_count\n;// 这行永远执行不到return0;}上面代码中good结尾结果为预想值bad结尾非预想值下面是解释核心差异并非lock_guard或手动加锁的安全性问题而是try-catch 的作用域范围改变了「异常对循环生命周期的影响」最终导致计数结果不同。我会拆解两种写法的执行流程清晰说明结果差异的原因。先明确核心前提我们的预设场景5个线程每个线程循环1000次i500时抛异常手动版try包整个循环结果≈25005线程×500次而lock_guard版try包单次迭代结果≠2500实际远大于你感知的“小于”是描述偏差本质是和预期不一致。一、两种写法的执行流程拆解1. incrementManualtry 包裹整个 for 循环voidincrementManual(inttimes){try{// try 覆盖【全部1000次循环】for(inti0;itimes;i){// times1000g_mutex.lock();if(i500)throw...;// 第501次循环触发异常g_count;g_mutex.unlock();}}catch(...){g_mutex.unlock();// 手动补解锁}}单个线程执行步骤i0 到 i499共500次循环每次正常lock() → count → unlock()累计计数500次i500lock()后抛异常 → 直接跳出整个 for 循环进入外层 catch → 手动unlock()异常处理后循环永久终止i501 到 999 都不会执行最终单个线程计数500次 → 5个线程总计 5×5002500和预期一致。2. incrementGuardtry 包裹单次循环迭代voidincrementGuard(inttimes){for(inti0;itimes;i){// times1000// try 仅覆盖【单次循环迭代】try{std::lock_guardstd::mutexlock(g_mutex);if(i500)throw...;g_count;}catch(...){std::cout捕获异常e.what()\n;}}}单个线程执行步骤i0 到 i499共500次循环每次正常lock_guard加锁 → count → 解锁累计计数500次i500lock_guard加锁后抛异常 →lock_guard析构自动解锁 → 异常被当前迭代的 catch捕获仅终止本次迭代关键catch 处理完后外层 for 循环不会终止程序回到循环头执行 i501i501 到 999共499次循环每次正常计数累计计数499次最终单个线程计数 500499999次 → 5个线程总计 5×9994995远大于预期的2500。二、结果差异的核心原因维度incrementManualtry包整个循环incrementGuardtry包单次迭代try-catch 作用域覆盖全部1000次循环仅覆盖单次循环迭代异常传播行为异常跳出整个 for 循环线程终止计数异常被本地catch捕获仅终止当前迭代循环继续单个线程计数次数500次0-499999次0-499 501-9995线程总计2500符合预期4995偏离预期你感知的“结果小于预设值”大概率是描述偏差本质是「异常是否终止整个循环」导致计数和预期2500不一致——而非lock_guard本身有缺陷。三、关键补充lock_guard 的安全性不受 try 位置影响无论 try-catch 包“整个循环”还是“单次迭代”lock_guard都能保证异常发生时自动解锁RAII 机制这是手动加锁永远比不了的核心优势。如果想让lock_guard版也输出 2500和手动版结果一致只需把 try-catch 移到循环外层和手动版对齐voidincrementSafeConsistent(inttimes){try{// try 包裹整个循环异常终止循环for(inti0;itimes;i){std::lock_guardstd::mutexlock(g_mutex);if(i500)throwstd::runtime_error(意外异常);g_count;}}catch(conststd::exceptione){std::cout捕获异常e.what()\n;}}修改后单个线程计数500次 → 5线程总计2500和手动版结果一致同时保留lock_guard自动解锁的优势无需手动处理解锁。总结核心差异try-catch 的作用域范围决定了异常是否终止整个循环——手动版终止循环lock_guard版仅终止单次迭代最终计数结果不同本质原因结果差异是「异常对循环生命周期的影响」导致而非锁的安全性问题最佳实践lock_guard搭配“try包裹整个循环”是最优解——既保证异常时自动解锁又能让计数结果符合预期且代码简洁、无手动解锁的风险。

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

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

立即咨询