1.多线程加锁
#include <mutex>
mutex mut;
mut.lock ();
mut.unlock ();
以下代码执行结果为200000000,证明没有发生val被一个线程获取处理还没写回的时候,被另一个线程读走。
如果不加锁,val的结果会是100000000到200000000之间的一个数。
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int val;
mutex mut;
void icrement () {
for (int i = 0; i < 100000000; i++) {
mut.lock ();
val++;
mut.unlock ();
}
}
int main (int argc, char* argv []) {
//创建两个线程
thread t1 (icrement);
thread t2 (icrement);
//等待两个线程执行完毕
t1.join ();
t2.join ();
cout << val << endl;
return 0;
}
2.线程池
c++实现:(头文件)
https://github.com/progschj/ThreadPool
线程池原理:线程池采用预创建的技术,在应用程序启动之后,将立即创建一定数量的线程(N1),放入空闲队列中。这些线程都是处于阻塞(Suspended)状态,不消耗CPU,但占用较小的内存空间。当任务到来后,缓冲池选择一个空闲线程,把任务传入此线程中运行。当N1个线程都在处理任务后,缓冲池自动创建一定数量的新线程,用于处理更多的任务。在任务执行完毕后线程也不退出,而是继续保持在池中等待下一次的任务。当系统比较空闲时,大部分线程都一直处于暂停状态,线程池自动销毁一部分线程,回收系统资源。
适合场景:
(1)单位时间内处理任务频繁而且任务处理时间短(线程创建和撤销占任务时间比重就大)
(2)对实时性要求较高。如果接受到任务后在创建线程,可能满足不了实时要求,因此必须采用线程池进行预创建。
#include <iostream>
#include "ThreadPool.h"
auto f(int n) {
std::this_thread::sleep_for(std::chrono:: milliseconds (1000));
std::cout<<"worker thread ID:"<<std::this_thread::get_id()<<std::endl;
return n;
}
int main()
{
// 创建线程池,参数是线程池中的线程数量
ThreadPool pool(4);
//.enqueue()让等待队列中的一个线程去执行f函数,参数依次列在后边
//没有空线程可用就等着
int times=10;
while(times--){
pool.enqueue(f, 100);
}
//使用get获得f函数处理的返回值,也可以直接不接受返回值
auto result = pool.enqueue(f, 3);
std::cout << result.get() << std::endl;
return 0;
}