【20天学C++】Day 19: 多线程编程
📅 学习时间:4-5小时
🎯 学习目标:掌握C++多线程基础
💡 难度:★★★★☆
1. 线程基础
1.1 创建线程
#include<iostream>#include<thread>usingnamespacestd;// 线程函数voidhello(){cout<<"Hello from thread!"<<endl;}voidprintNumber(intn){for(inti=0;i<n;i++){cout<<i<<" ";}cout<<endl;}intmain(){// 创建线程threadt1(hello);// 带参数threadt2(printNumber,5);// Lambdathreadt3([](){cout<<"Lambda thread"<<endl;});// 等待线程结束t1.join();t2.join();t3.join();cout<<"主线程结束"<<endl;return0;}1.2 join和detach
#include<iostream>#include<thread>#include<chrono>usingnamespacestd;voidwork(intseconds){this_thread::sleep_for(chrono::seconds(seconds));cout<<"工作完成,耗时"<<seconds<<"秒"<<endl;}intmain(){threadt1(work,2);// join:等待线程结束t1.join();// 主线程阻塞,直到t1结束threadt2(work,3);// detach:分离线程(后台运行)t2.detach();// 注意:主线程结束后,t2可能还没完成// 必须join或detach,否则析构时会terminate// thread t3(work, 1); // ❌ 没有join或detachcout<<"主线程继续"<<endl;this_thread::sleep_for(chrono::seconds(4));// 等待detach的线程return0;}1.3 线程信息
#include<iostream>#include<thread>usingnamespacestd;intmain(){// 获取线程IDcout<<"主线程ID: "<<this_thread::get_id()<<endl;threadt([](){cout<<"子线程ID: "<<this_thread::get_id()<<endl;});cout<<"t的ID: "<<t.get_id()<<endl;// 硬件并发数cout<<"CPU核心数: "<<thread::hardware_concurrency()<<endl;t.join();return0;}2. 互斥锁
2.1 mutex基础
#include<iostream>#include<thread>#include<mutex>usingnamespacestd;intcounter=0;mutex mtx;voidincrement(){for(inti=0;i<100000;i++){mtx.lock();// 加锁counter++;mtx.unlock();// 解锁}}intmain(){threadt1(increment);threadt2(increment);t1.join();t2.join();cout<<"counter = "<<counter<<endl;// 200000return0;}2.2 lock_guard(RAII)
#include<iostream>#include<thread>#include<mutex>usingnamespacestd;intcounter=0;mutex mtx;voidincrement(){for(inti=0;i<100000;i++){// lock_guard:自动加锁解锁lock_guard<mutex>lock(mtx);counter++;// 作用域结束自动解锁}}intmain(){threadt1(increment);threadt2(increment);t1.join();t2.join();cout<<"counter = "<<counter<<endl;return0;}2.3 unique_lock
#include<iostream>#include<thread>#include<mutex>usingnamespacestd;mutex mtx;voidflexible(){// unique_lock更灵活unique_lock<mutex>lock(mtx);// 可以手动解锁lock.unlock();// 可以重新加锁lock.lock();// 可以尝试加锁if(lock.try_lock()){// 成功}// 可以转移所有权unique_lock<mutex>lock2=move(lock);}intmain(){threadt(flexible);t.join();return0;}3. 条件变量
#include<iostream>#include<thread>#include<mutex>#include<condition_variable>#include<queue>usingnamespacestd;queue<int>dataQueue;mutex mtx;condition_variable cv;boolfinished=false;voidproducer(){for(inti=1;i<=10;i++){{lock_guard<mutex>lock(mtx);dataQueue.push(i);cout<<"生产: "<<i<<endl;}cv.notify_one();// 通知消费者this_thread::sleep_for(chrono::milliseconds(100));}{lock_guard<mutex>lock(mtx);finished=true;}cv.notify_all();}voidconsumer(){while(true){unique_lock<mutex>lock(mtx);// 等待条件:队列非空或已结束cv.wait(lock,[](){return!dataQueue.empty()||finished;});while(!dataQueue.empty()){intdata=dataQueue.front();dataQueue.pop();cout<<"消费: "<<data<<endl;}if(finished&&dataQueue.empty())break;}}intmain(){threadprod(producer);threadcons(consumer);prod.join();cons.join();return0;}4. 原子操作
#include<iostream>#include<thread>#include<atomic>usingnamespacestd;atomic<int>counter(0);// 原子变量voidincrement(){for(inti=0;i<100000;i++){counter++;// 原子操作,无需加锁}}intmain(){threadt1(increment);threadt2(increment);t1.join();t2.join();cout<<"counter = "<<counter<<endl;// 200000// 原子操作atomic<int>a(10);a.store(20);// 存储intval=a.load();// 读取intold=a.exchange(30);// 交换// CAS操作intexpected=30;a.compare_exchange_strong(expected,40);return0;}5. async和future
#include<iostream>#include<future>#include<chrono>usingnamespacestd;intcompute(intx){this_thread::sleep_for(chrono::seconds(2));returnx*x;}intmain(){// async:异步执行future<int>result=async(launch::async,compute,10);cout<<"计算中..."<<endl;// get():获取结果(阻塞直到完成)intvalue=result.get();cout<<"结果: "<<value<<endl;// 多个异步任务autof1=async(launch::async,compute,5);autof2=async(launch::async,compute,10);autof3=async(launch::async,compute,15);cout<<f1.get()+f2.get()+f3.get()<<endl;return0;}5.1 promise
#include<iostream>#include<thread>#include<future>usingnamespacestd;voidworker(promise<int>&prom){// 做一些工作this_thread::sleep_for(chrono::seconds(1));// 设置结果prom.set_value(42);}intmain(){promise<int>prom;future<int>fut=prom.get_future();threadt(worker,ref(prom));cout<<"等待结果..."<<endl;intresult=fut.get();cout<<"结果: "<<result<<endl;t.join();return0;}6. 线程安全的单例
#include<iostream>#include<mutex>usingnamespacestd;classSingleton{private:staticSingleton*instance;staticonce_flag flag;Singleton(){cout<<"创建单例"<<endl;}public:staticSingleton*getInstance(){call_once(flag,[](){instance=newSingleton();});returninstance;}};Singleton*Singleton::instance=nullptr;once_flag Singleton::flag;// 更简单的方式(C++11保证线程安全)classSingleton2{Singleton2(){}public:staticSingleton2&getInstance(){staticSingleton2 instance;// 线程安全returninstance;}};intmain(){autos1=Singleton::getInstance();autos2=Singleton::getInstance();cout<<(s1==s2)<<endl;// 1return0;}7. 小结
[线程基础] 1. thread创建线程 2. join()等待线程 3. detach()分离线程 [同步原语] 4. mutex互斥锁 5. lock_guard自动锁 6. unique_lock灵活锁 7. condition_variable条件变量 [原子操作] 8. atomic<T>原子类型 9. 无锁编程 [异步] 10. async异步执行 11. future获取结果 12. promise设置结果 [线程安全] 13. call_once单次执行 14. 静态局部变量单例下一篇预告:Day 20 - 综合项目与进阶