码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 利用C++11 实现:迷你线程池+CAS自旋锁


    文章目录

    • 1. 概述
    • 2. 代码实现

    1. 概述

    最近有学习一些关于C++11从语法层面上提供的多线程编程。本来考虑使用C++11的互斥锁来实现线程间的互斥,而C++提供的互斥锁是比较简单的,和Linux的使用没有太大区别。

    另一方面,在面试的时候,会涉及一些无锁的互斥手法。比如:在webserver项目中,请求队列的任务在出队和入队上都需要互斥锁。而互斥锁比较重,需要执行系统调用。而系统调用又需要陷入内核态,调度完切换回用户态又需要时间,因此效率较低。这时候,采用CAS+自旋锁的手法效率会比较高。

    因此,下面的例子借鉴陈硕大神在muduo网络库实现一个迷你版的线程池。在这个线程池中,我们把线程类Thread和线程池类ThreadPool进行解耦,让模块与模块之间的耦合度更低。在实现细节上:

    1. 其中,ThreadPool类定义了线程池中的子线程的工作函数runInThread,这个在muduo网络库里面其实是开发了个接口给用户进行定义的,但是在这里我们没有提供这个借口,感兴趣的读者可以自行拓展封装。

    2. 我们实现了一个CAS类的自旋锁,其实现使用了C++11提供的原子类atomic。

    2. 代码实现

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    int mutex = 0;
    int lock = 1;
    int unlock = 0;
    
    class CAS {
    public:
    	CAS() : flag(false) {}
    
    	// 上锁
    	void lock() {
    		bool expect = false;
    		// 1. 如果flag的值(锁的值)和期望的值相等,那么将新的值赋给flag,返回true
    		// 2. 如果flag的值(锁的值)和期望值不相等,那么将flag的值赋给expect,返回false,因此每次都要重置expect
    		while (!flag.compare_exchange_weak(expect, true)) {
    			expect = false;
    		}
    	}
    
    	// 解锁
    	void unlock() {
    		flag.store(false);
    	}
    
    private:
    	CAS(const CAS&) = delete;
    	CAS& operator=(const CAS&) = delete;
    	atomic<bool> flag; // false为解锁状态 true为上锁状态
    };
    
    
    class Thread {
    public:
    	Thread(function<void()> func) : func_(func) {}
    
    	thread start() {
    		thread t(func_);
    		return t;
    	}
    
    private:
    	function<void()> func_;
    };
    
    class ThreadPool {
    public:
    
    	void startPool(int poolSize) {
    		for (int i = 0; i < poolSize; ++i) {
    			pool_.push_back(new Thread(bind(&ThreadPool::runInPool, this, i)));
    		}
    
    		for (int i = 0; i < poolSize; ++i) {
    			handler_.push_back(pool_[i]->start());
    		}
    
    		for (int i = 0; i < poolSize; ++i) {
    			handler_[i].join();
    		}
    	}
    
    private:
    	// 工作函数
    	void runInPool(int threadId) {
    		mutex_.lock();
    		cout << "Thread start! Thread Id:" << threadId << endl;
    		mutex_.unlock();
    	}
    
    	vector<Thread*> pool_;
    	vector<thread> handler_;
    
    	CAS mutex_;
    };
    
    
    int main() {
    
    	ThreadPool pool;
    	pool.startPool(10);
    
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
  • 相关阅读:
    代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
    java计算机毕业设计学生日常事务管理系统源码+mysql数据库+lw文档+系统+调试部署
    软件开发 23个设计模式收集
    DJYOS推荐:DJYOS给嵌入式软件开发带来的跨越
    设置服务账号Service Accounts(sa)的token不挂载到pod
    GIS工具maptalks开发手册(四)02——渲染地图信息框之添加绘制工具 & 获取面的坐标数据信息框进行展示 & 渲染图片的两种方式
    方法递归详解
    机器学习笔记 - 时间序列使用机器学习进行预测
    通过融合UGV的地图信息和IMU的惯性测量数据,实现对车辆精确位置和运动状态的估计和跟踪研究(Matlab代码实现)
    基于rt thread smart构建EtherCAT主站
  • 原文地址:https://blog.csdn.net/zsiming/article/details/126612407
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号