C++学习之线程详解
多线程是开发中必不可少的往往我们需要多个任务并行就需要多线程开发就好比图像检测和图像结果的处理这就是一个可闭环的任务用多线程是可以加速这个任务的线程的状态就绪态线程能够运行正在等待处理机资源运行态正在运行可能有多个线程处于运行态阻塞态线程由于等待某些条件而无法运行例如IO、锁、互斥量等终止态线程从起始函数返回或被取消多线程的构建有三种方式可以构建多线程前提是都需要引入pthread.h这个头文件1、函数2、仿函数3、Lambda表达式三者的本质都是在调用函数1234567891011// 函数方式voidfun(string s){cout sendl;coutfirst thread programmsendl;}intmain(){string s Hell world;threadth thread(fun, s);th.join();}上面代码为最简单线程的一个构造join函数是一个等待线程完成函数主线程需要等待子线程运行结束才可以结束还有一个detach的函数会让线程在后台运行需要等到程序退出才结束计算时间计算时间在这里介绍两种方式一、程序运行时间12345678longn 0;clock_tstart,finish;startclock();while(n1000000000)n;finishclock();printf(spend time %f s \n, (double)(finish-start)/CLOCKS_PER_SEC);printf(spend time %f ms \n, (double)(finish-start)/1000);这种方式和系统时间无关一般用来调试时打印时间二、chrono123456789101112#include chrono//方式三 chronostd::chrono::system_clock::time_point Cstart std::chrono::system_clock::now();//系统时间// std::chrono::steady_clock::time_point Cstart std::chrono::steady_clock::now(); //稳定时间longn 0 ;while(n1000000000)n;std::chrono::system_clock::time_point Cend std::chrono::system_clock::now();//系统时间std::chrono::durationfloat spend_time Cend-Cstart;coutspend_time.count()endl;这个方式用系统时间进行计算在实际程序中用这个方式共享资源和互斥锁关于互斥锁的概念引用这篇博主的讲解文章引入互斥锁原因当有两个线程共享一块资源时容易造成冲突也就是上个线程还没结束就进行下个线程举个例子就是读写操作添加互斥锁可以很好的解决这个冲突问题互斥锁是个简单的加锁方法互斥锁只有两种状态上锁lock和解锁unlock互斥锁特点1、原子性把一个互斥量锁定为一个原子操作这意味着如果一个线程锁定了一个互斥量没有其他线程在同一时间可以成功锁定这个互斥量2、唯一性如果一个线程锁定了一个互斥量在它解除锁定之前没有其他线程可以锁定这个互斥量3、非繁忙等待如果一个线程已经锁定了一个互斥量第二个线程又试图去锁定这个互斥量则第二个线程将被挂起不占用任何cpu资源直到第一个线程解除对这个互斥量的锁定为止第二个线程则被唤醒并继续执行同时锁定这个互斥量。互斥锁的使用12345mutex mtx;//创建互斥锁对象mtx.lock();g_pcm_elapseds.push_back(std::make_pair(pcm_data, elapsed));// 执行语句mtx.unlock();condition_variablecondition_variable条件变量可以阻塞wait调用的线程直到使用notify_one或notify_all通知恢复为止使用案例12345678910111213141516171819202122232425262728std::mutex mtx;std::condition_variable cv;boolready false;voidprint_thread_id(intid){std::unique_lockstd::mutex lck(mtx);cv.wait(lck,[]{returnready;});std::coutthreadid endl;}voidgo(){std::unique_lockstd::mutex lck(mtx);ready true;cv.notify_all();// 唤醒所有线程};intmain(){std::threadthreads[10];for(inti0;i10;i){threads[i] std::thread(print_thread_id,i);}std::cout thread read all doneendl;go();for(auto th:threads) th.join();return0;}线程池作用每一个任务都起一个线程这样的效率是不高的起一个线程池哪个线程空闲就来处理任务这样的结构高效