首页 > 其他分享 >项目八股[日志系统]

项目八股[日志系统]

时间:2023-09-08 19:34:39浏览次数:42  
标签:八股 变量 队列 lock 系统 线程 条件 日志

日志系统涉及到的C++特性语法 用了一个锁+两个条件变量,跟线程池不一样 只用了一个锁一个条件变量

C++11提供的 condition_variable 类是一个同步原语,它能够阻塞一个或者多个线程,直到另一线程修改共享变量并通知 condition_variable。

对比POSIX的pthread_cond,pthread移植性好,condition_variable则是配合RAII机制更为灵活,像unique_lock可以随时加锁不用手动,离开作用域后自动解锁

1.单例模式

2.lock_guard<mutex> locker(mtx);

lock_guard和unique_lock怎么区分,我发现代码里用到了锁+条件变量的地方就会用unique_lock,其他地方都是单lock_guard

 简单地讲,unique_lock 是 lock_guard 的升级加强版,它具有 lock_guard 的所有功能,同时又具有其他很多方法,使用起来更强灵活方便,能够应对更复杂的锁定需要。

  • 作用域规则同 lock_grard,析构时自动释放锁
  • 不可复制,可移动
  • 条件变量需要该类型的锁作为参数(此时必须使用 unique_lock)

 

3.fputs(str.c_str(), fp);

4.fflush(fp);

 

 

阻塞队列

队列是容器适配器,默认实现底层用的deque,deque本身是一个序列式容器,它的迭代器不支持随机访问,所以查找效率不高O(n)。插入删除效率比较高 因为不需要移动后续元素O(1)

vector也是个序列式容器,因为支持随机下标访问,所以查找效率很高O(1),但是它除了在头尾插入比较高效,其他位置插入都需要移动后续的元素,所以插入复杂度O(n)。

所以总体来说是看构造这个容器适配器时的需求,如果说不要求频繁的随机访问,那么用deque,如果说不要求在中间进行频繁插入删除,那么用vector,其他情况下两者都行。

 

 

日志系统是懒汉模式,也就是C++11之后的局部静态实现的单例模式,内部会维护一个日志消息队列,作为采用异步模式下的写入中介。日志系统头文件里定义了四个宏作为写入的接口方便在主线程与工作线程需要的地方进行传参使用。

日志系统是一个典型的生产者消费者模型,其他线程是生产者,日志线程是唯一的消费者,他们之间进行数据交互是依赖日志消息队列,所以日志消息队列的设计需要解决线程安全(互斥与同步的问题)和预防日志队列过度增长导致长时间高频触发增长使得资源耗尽的问题。

template<class T>
void BlockQueue<T>::push(const T &item) {
    std::unique_lock<std::mutex> locker(mtx);
    while(que.size() >= capacity_) {
        condProducer.wait(locker);
    }
    que.push(item);
    condConsumer.notify_one();
}

为什么有锁还要用条件变量?

为什么要单独一个日志线程 因为日志线程要进行大量的对同一个日志文件的写入,很多线程互斥着等待上锁读写效率很低。 同步的话生产者等待写入日志的函数返回效率也低。所以异步管理比较好。

因为条件变量能实现逻辑功能的同步问题,如果没有条件变量,生产者的情况会变成,多个生产者在反反复复的上锁 查看可否写入 再解锁 但实际上只有消费者抢到锁了 消费了一个日志信息,生产者才有写入的条件,而此时消费者抢到锁的概率很很低了。、

中级挂起再唤醒抢锁效率很低,不如用条件变量去维护逻辑顺序的同步,也就是用到两个条件变量进行互相唤醒,生产者写入了唤醒消费者,消费者消费了唤醒生产者。

为什么要用while循环而不是if 因为会存在虚假唤醒的可能。

比如有ab两个生产者进程 一个c消费者进程,生产效率高导致队列逐渐满了,然后a线程率先因为队列满了写不下了而进入条件变量wait,它进入条件变量的条件是队列满了,可是醒来并试图往下执行的时候,队列就一定是空的吗?不一定,因为可能c在试图唤醒生产者所有线程的时候,b却没在wait的等待队列里,甚至还没进while循环,但它此时抢到锁了(然后没进入while就向下执行)并且又把队列满上了。而a呢,a因为自己是不满足一个条件之后才wait并且释放锁的,它处在条件变量的等待队列里,第一次唤醒时没能抢到锁,后续不用再等待条件变量了,只要抢到锁就应该能向下执行,但它能上锁的时候,条件(队列没满能向下执行)却未必满足了,但它没用while循环去再次判断条件,所以它在队列满着的情况下向下执行,此时就会出问题。

而用while循环,醒来之后要向下执行首先需要再次判断一下while,就避免了在队列已经达到预期上限情况时还向下执行的问题。

 

标签:八股,变量,队列,lock,系统,线程,条件,日志
From: https://www.cnblogs.com/synapse331/p/17687871.html

相关文章

  • 酒店预定的系统设计与实现-计算机毕业设计源码+LW文档
    随着计算机信息技术的发展,各种管理系统逐渐用在社会生产生活中,通过系统化管理提高办事流程,节约时间。在酒店,存在许多的服务内容,如客房预定、信息咨询、人员管理等等,这些复杂的业务信息单靠人工管理,费时费力,还容易出错。如果通过酒店管理系统进行系统化管理,可以有效的解决酒店的整个......
  • XP系统无法访问Mysql 8.0.32数据库的问题
    之前一个项目,客户那边突然反应软件的数据库都访问不了了。这之前他们升级过MYSQL数据库的版本,更新到了最新的版本。我们的应用,因为需要兼容XP系统,所以当时用的是.NETFramework4.0。MySQL的驱动库在6.9.12之后就不支持.NET4.0了。所以我们用的MySQL库是6.9.12的,这个版本的库......
  • 课程教学要素管理系统设计与实现-计算机毕业设计源码+LW文档
    1.选题背景、意义随着科技的进步与发展,计算机的诞生给人们的工作和学习带来了极大的改变,人类从工业时代进入了信息时代。今天,计算机对社会的影响不断深入扩大,教育行业也不例外。在此之前,计算机对教育的影响大多局限在科研领域或者计算机领域的教学。从上个世纪七十年代中期,计算......
  • 基于安防监控 EasyCVR 视频汇聚融合技术的运输管理系统进行简要分析。
    一、项目背景近年来,随着物流行业的快速发展,出现了一些问题,如高运输费用、运输过程不透明、货损货差率高、供应链协同能力差等,这严重影响了物流作业效率。因此,市场对于运输管理数字化的需求变得更加迫切。当前运输行业存在以下难题:1.运力池资源分配不均,导致运输时效不稳定。2.货......
  • 设置Vmware,使局域网也可以访问虚拟机系统中的服务
    一、虚拟机设置1.右击虚拟机-可移动设备-网络适配器-设置中2.选择NAT模式3.通过root账号,登陆到系统中,输入dhclient获取ip。(dhclient-r为释放ip)输入#ipa查看ip信息。192.168.86.129及为该虚拟机ip;在该虚拟机上部署好你自己的服务,在防火墙上开放好端口号(如不会开放端口......
  • [书目20230908]信息系统项目管理师教程
    第1章 信息化发展11.1 信息与信息化11.1.1 信息21.1.2 信息系统21.1.3 信息化41.2 现代化基础设施71.2.1 新型基础设施建设71.2.2 工业互联网81.2.3 车联网101.3 现代化创新发展121.3.1 农业农村现代化121.3.2 两化融合与智能制造131.3.3 消......
  • 从零开始搭建EasyDarwin环境——linux系统开发环境nodejs的搭建
    EasyDarwin是目前比较热门的开源平台之一,上一篇我们给大家详细展示了搭建EasyDarwin环境前实现虚拟机Linux系统共享目录,本文我们将说明一下如何在Linux下搭建起nodejs环境。1.首先安装wgetyuminstall-ywget如果已经安装了可以跳过该步骤。2.下载nodejs最新的bin包可以在下载页......
  • 小区物业报修系统的设计与实现-计算机毕业设计源码+LW文档
    随着经济的发展,科技的进步,网络逐渐发达,信息产业不断改良,计算机事业也在不断地发展,人们生活水平也得到了提高。随着人们生活节奏的不断加快,高质量的生活水平以及较优越的生活环境越来越成为人们所追求的目标。但是相应的,这样也会加强人们的劳动量,居民的生活节奏也随之慢慢的加快。长......
  • 拉新大厅平台系统软件定制
      拉新市场竞争对手多,在这样的环境下,想要通过吸引用户参与进来,肯定需要花花大价钱才能实现每天的任务量。拉新大厅平台软件的开发设计,作为一种有针对性的解决方案,能够有效地解决这一问题。  拉新大厅平台系统软件定制,需要先把软件的需求确定下来,就是根据企业的实际需求和......
  • 骑手端后台管理系统app源码
      骑手端app管理软件是基于外卖平台的其中一个端的软件,骑手端的功能从从订单接收、派送分配、路线规划、到订单完成的整个过程。本文主要解析该App源码的关键技术和实现方式。  骑手端的APP软件端,是接当地所有的外卖订单的系统,用户下单后的订单编号,所有的骑手都可以抢单子......