【基础分析】——线程、锁、条件变量

发布时间:2026/5/18 14:28:15

【基础分析】——线程、锁、条件变量 先理解核心场景生产者-消费者模型这段代码模拟的是生活中工厂生产商品顾客消费商品的场景生产者线程负责往仓库队列里放商品数字消费者线程负责从仓库里取商品数字核心问题要保证仓库不会被同时操作比如生产和消费撞车消费者不会去拿空仓库里的东西逐部分拆解代码零基础友好版1. 全局变量公共资源std::queueintq;// 仓库队列存数字商品std::mutex mtx;// 仓库的锁只有拿到锁才能动仓库std::condition_variable cv;// 通知器生产者喊消费者“有货了”队列q像排队买奶茶先放进去的数字先被拿出来先进先出锁mtx仓库门的钥匙同一时间只有一个人能拿到钥匙开门条件变量cv生产者喊“仓库有货了快来取”2. 生产者函数生产商品voidproducer(){// 生产9个数字0-8for(inti0;i9;i){{// 这个大括号是“锁的作用范围”出了括号自动解锁// 上锁拿到仓库钥匙别人暂时不能动仓库std::lock_guardstd::mutexlock(mtx);q.push(i);// 把数字i放进仓库std::cout生产istd::endl;// 打印生产信息}// 解锁用完钥匙还回去Sleep(1000);// 休息1秒模拟生产需要时间cv.notify_one();// 喊一声有货了通知消费者}}通俗解释生产者每次生产一个数字先拿钥匙打开仓库门上锁把数字放进去然后还钥匙解锁生产一个歇1秒模拟真实生产耗时生产完喊一声告诉消费者“有新货了”3. 消费者函数消费商品voidconsumer(){// 死循环一直等着消费直到消费到6就退出while(1){// 上锁拿仓库钥匙unique_lock是可以临时解锁的锁适合等通知std::unique_lockstd::mutexlock(mtx);// 等通知如果仓库空就放下钥匙等仓库有货了再拿钥匙继续cv.wait(lock,[](){return!q.empty();});// 仓库有货了开始消费intvq.front();// 取仓库里第一个商品q.pop();// 把这个商品从仓库拿走std::cout消费vstd::endl;// 打印消费信息// 消费到6就停止退出死循环if(v6)break;}}通俗解释消费者一直等着先拿钥匙但如果仓库空了就把钥匙放下等着生产者喊“有货了”等生产者喊了之后再拿钥匙从仓库里取第一个数字拿走并打印只要拿到数字6就不消费了直接走人4. 主函数启动程序intmain(){// 创建两个线程t1是生产者t2是消费者std::threadt1(producer);std::threadt2(consumer);// 等待线程结束主线程等t1、t2都干完活再结束程序t1.join();t2.join();return0;}通俗解释老板main函数招了两个员工t1负责生产t2负责消费join()老板不先走等两个员工都干完活再关门下班代码运行过程零基础能懂的流程程序启动同时启动生产者和消费者线程生产者先生产0 → 歇1秒 → 喊消费者消费者拿到0消费0生产者生产1 → 歇1秒 → 喊消费者消费者拿到1消费1以此类推直到生产者生产6消费者消费6后直接退出不再消费生产者还会继续生产7、8但消费者已经走了这两个数字会留在仓库里生产者生产完9个数字后也退出程序结束总结核心要点线程就是同时干两件事生产和消费像工厂里的两个工人锁mutex保护公共仓库防止生产和消费同时操作避免乱套条件变量cv解决“消费者白等”问题生产者有货了才通知消费者不用消费者一直傻等。

相关新闻