web服务器改进:迷你线程池+CAS自旋锁(Demo)

本文介绍了一种基于C++11标准的无锁线程池实现方案,利用CAS操作配合自旋锁提高多线程环境下的任务调度效率。通过解耦线程类与线程池类,降低模块间耦合度,并给出完整代码示例。

1. 概述

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

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

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

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

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

2. 代码实现

#include <iostream>
#include <thread>
#include <mutex>
#include <functional>
#include <vector>
#include <atomic>
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;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值