int n=10的sizeof 为什么是四_mongodb内核源码实现、性能调优( 二 )


1. //ServiceStateMachine::_scheduleNextWithGuard 启动新的conn线程2. Status ServiceExecutorSynchronous::schedule(Task task, ScheduleFlags flags) {3.//如果_stillRunning为false,则直接返回4.if (!()) {5.return Status{ErrorCodes::ShutdownInProgress, "Executor is not running"};6.}7.//队列不为空,说明由任务需要运行,同步线程模型只有新连接第一次通过SSM进入该函数的时候为空8.//其他情况都不为空9.if (!()) {10.//kMayYieldBeforeSchedule标记当返回客户端应答成功后,开始接收下一个新请求,这时候会设置该标记11.if (flags & ScheduleFlags::kMayYieldBeforeSchedule) {12.//也就是如果该链接对应的线程如果连续处理了0xf个请求,则需要休息一会儿13.if ((_localThreadIdleCounter++ & 0xf) == 0) {14.//短暂休息会儿后再处理该链接的下一个用户请求15.//实际上是调用TCMalloc MarkThreadTemporarilyIdle实现16.markThreadIdle();17.}18.//链接数即线程数超过了CPU个数,则每处理完一个请求,就yield一次19.if (() > _numHardwareCores) {20.stdx::this_thread::yield();//线程本次不参与CPU调度,也就是放慢脚步21.}22.}23.//带kMayRecurse标识,说明即将调度执行的是dealTask24.//如果递归深度小于synchronousServiceExecutorRecursionLimit,则执行task25.if ((flags & ScheduleFlags::kMayRecurse) &&26.(_localRecursionDepth < ())) {27.++_localRecursionDepth;28.//递归深度没有超限,则直接执行task,不用入队29.task();30.} else {31.//入队,等待32.(std::move(task));33.}34.return Status::OK();35.}36.//创建conn线程,线程名conn-xx(实际上是从listener线程继承过来的,这时候的Listener线程是父线程,在37.//ServiceStateMachine::start中已通过线程守护ThreadGuard改为conn-xx),执行对应的task38.Status status = launchServiceWorkerThread([ this, task = std::move(task) ] {39.//说明来了一个新链接,线程数自增40.int ret = (1);41.//新链接到来的第一个任务实际上是readTask任务42.(std::move(task));43.while (!() && Relaxed()) {44.//每次任务如果是通过线程私有队列获取运行,则恢复递归深度为初始值145._localRecursionDepth = 1;46.//取出该线程拥有的私有队列上的第一个任务运行47.()();48.//该任务已经执行完毕,把该任务从队列移除49.();50.}51.//走到这里说明线程异常了或者需要退出,如链接关闭,需要消耗线程52.......53.});54.return status;55. }
从上面的代码可以看出,工作线程通过控制task任务的递归深度,当递归深度超过最大深度值,则把任务到队列,然后从队列获取task 任务执行 。
此外,为了达到性能的极致发挥,在每次执行task 任务的时候做了如下细节设计,这些细节设计在高压力情况下,可以提升5%的性能提升:
1)每运行oxf 次任务,就通过()让线程idle休息一会儿
2)如果线程数大于CPU 核数,则每执行一个任务前都让线程yield()一次
该模块函数接口总结大全
同步线程模型所有接口及其功能说明如下表所示:
3. 动态线程模型设计原理及核心代码实现
动态线程模型,会根据当前系统的访问负载动态的调整线程数,当线程CPU工作比较频繁的时候,控制线程增加工作线程数;当线程CPU比较空闲后,本线程就会自动销毁退出,总体工作线程数就会减少 。
动态线程模型核心源码实现
动态线程模型核心代码实现由ive 负责完成,该类核心成员变量及核心函数接口如下:
1. class ServiceExecutorAdaptive : public ServiceExecutor {2. public:3.//初始化构造4.explicit ServiceExecutorAdaptive(...);5.explicit ServiceExecutorAdaptive(...);6.ServiceExecutorAdaptive(...) = default;7.ServiceExecutorAdaptive& operator=(ServiceExecutorAdaptive&&) = default;8.virtual ~ServiceExecutorAdaptive();9.//控制线程及worker线程初始化创建10.Status start() final;11.//shutdown处理12.Status shutdown(Milliseconds timeout) final;13.//任务调度运行14.Status schedule(Task task, ScheduleFlags flags) final;15.//adaptive动态线程模型对应Mode16.Mode transportMode() const final {17.return Mode::kAsynchronous;18.}19.//统计信息20.void appendStats(BSONObjBuilder* bob) const final;21.//获取runing状态22.int threadsRunning() {23.return ();24.}25.//新键一个worker线程26.void _startWorkerThread();27.//worker工作线程主循环while{}处理28.void _workerThreadRoutine(int threadId, ThreadList::iterator it);29.//control控制线程主循环,主要用于控制什么时候增加线程30.void _controllerThreadRoutine();31.//判断队列中的任务数和可用线程数大小,避免任务task饥饿32.bool _isStarved() const;33.//asio网络库io上下文34.std::shared_ptr _ioContext; //早期ASIO中叫io_service35.//TransportLayerManager::createWithConfig赋值调用36.std::unique_ptr