自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(101)
  • 收藏
  • 关注

转载 用C++实现数据总线的方法系列(下):消息总线和消息处理

用C++实现数据总线的方法系列(下):消息总线和消息处理原文: link.本文实现一个完整功能的消息总线MessageBus,同时介绍下消息的处理方法。这里定义了消息类型的枚举MesageType,消息优先级的枚举MessagePriority,以及消息的结构类Message,它包含消息类型(type),消息优先级(priority)和消息数据(info)。同时定义了MessagePtr作为Message的指针指针类。消息总线MessageBus的实现和数据总线一样,需要有存放消息的消息链表,构成锁

2021-04-16 13:27:40 1117

转载 用C++实现数据总线的方法系列(中):数据总线的实现

用C++实现数据总线的方法系列(中):数据总线的实现原文: link.数据总线以及传输的数据的定义和实现传输数据类Data,它是由数据的地址和数据的大小两个成员组成的。数据总线类DataQueue,需要有存放总线数据的数据链表,构成锁的互斥量和用于多线程同步的条件变量,同时也需要具有最基本的Push和Pop函数,还有就是Clear和Empty函数。#ifndef DATA_QUEUE_H#define DATA_QUEUE_H#include<stdint.h>#include

2021-04-16 11:29:49 1165 1

转载 用C++实现数据总线的方法系列(上):基本概念&同步队列

用C++实现数据总线的方法系列(上):基本概念&同步队列原文链接:link.本文主要介绍多线程中数据同步的方法,技术包括:线程锁,同步变量,原子变量,消息处理等;以及三种同步队列的实现方法。1.std::unique_lock与std:::lock_gurad基本一致,但更加灵活的锁管理类模板,构造时是否加锁是可选的,在对象析构时如果持有锁会自动释放锁,所有权可以转移。对象生命期内允许手动加锁和释放锁。但提供了更好的上锁和解锁控制接口(lock,try_lock,try_lock_for,t

2021-04-09 14:13:15 620

原创 Adb 命令开 log level

一、 Adb 命令开 log level为了避免log太多,还有快速定位问题,mtk平台有一些log开关。想要logcat中看到一些log,就需要打开相应的开关。所以这里整理一些log开关,相互学习,也做备忘之效在开 Camera 各模块 log level 前,建议先关闭 selinux 权限,并确定 logD 是已经有打印的,如果没有打印可以用如下命令开启:adb shell setenforce 0adb shell setprop persist.vendor.mtk.camera.log

2021-03-03 13:22:24 2454

原创 MTK Camera HAL3相关代码路径

Camera相关模块 代码路径CameraService --frameworks/av/services/camera/libcameraservice/CameraService.cppCameraHALServer --mtkcam3/main/hal/service/service.cppICameraProvider --mtkcam/main/hal/devicemgr/provider/2.4/CameraProviderImpl.cppICameraDevice --mtk

2021-02-04 10:53:37 614 1

原创 深入理解C++11(十)(3)

深入理解C++11(十)(3)原子变量C++11提供了一个原子类型std::atomic,可以使用任意类型作为模板参数,C++11内置了整型的原子变量,可以更方便地使用原子变量,使用原子变量就不需要使用互斥量来保护该变量了,用起来更简洁。例如,要做一个计数器,使用mutex时是这样的,如代码清单5-7所示:struct Counter{int value;std::mutex mutex;void increment(){std::lock_guard<std::mutex>

2021-01-12 16:35:39 93

原创 深入理解C++11(十)(2)

深入理解C++11(十)(2)条件变量条件变量是C++11提供的另外一种用于等待的同步机制,它能阻塞一个或多个线程,直到收到另外一个线程发出的通知或者超时,才会唤醒当前阻塞的线程。条件变量需要和互斥量配合起来用。C++11提供了两种条件变量:·condition_variable,配合std::unique_lock进行wait操作。·condition_variable_any,和任意带有lock、unlock语义的mutex搭配使用,比较灵活,但效率比condition_variable差一些

2021-01-12 10:39:20 152

原创 深入理解C++11(十)(1)

深入理解C++11(十)C++11之前,C++语言没有对并发编程提供语言级别的支持,这使得我们在编写可移植的并发程序时,存在诸多不便。现在C++11增加了线程以及线程相关的类,很方便地支持了并发编程,使得编写的多线程程序的可移植性得到了很大的提高。线程的创建用std::thread创建线程非常简单,只需要提供线程函数或者函数对象即可,并且可以同时指定线程函数的参数。下面是创建线程的示例:#include <thread>void func(){// do some work}i

2021-01-11 14:28:38 96

原创 深入理解C++11(二十)

深入理解C++11(二十)可变参数模板消除重复代码可变参数模板的一个特性是参数包中的模板参数可以是任意数量和任意类型的,因此,可以以一种更加泛化的方式去处理一些问题,比如一个泛型的打印函数,在C++11之前,要写一个通用的打印函数可能不得不像代码清单3-3这样写。template<typename T>void Print(T t){cout<<t<<endl;}template<typename T1, typename T2>void P

2021-01-06 16:28:01 115 1

原创 深入理解C++11(十九)(摘录)

深入理解C++11(十九)可变参数模板类可变参数模板类是一个带可变模板参数的模板类,第1章中介绍的std::tuple就是一个可变模板类,它的定义如下:template< class... Types >class tuple;这个可变参数模板类可以携带任意类型任意个数的模板参数:std::tuple<int> tp1 = std::make_tuple(1);std::tuple<int, double> tp2 = std::make_tuple(1,

2021-01-06 16:10:27 123

原创 深入理解C++11(十六)

深入理解C++11(十六)unordered container无序容器C++11增加了无序容器unordered_map/unordered_multimap和unordered_set/unordered_multiset,由于这些容器中的元素是不排序的,因此,比有序容器map/multimap和set/multiset效率更高。map和set内部是红黑树,在插入元素时会自动排序,而无序容器内部是散列表(Hash Table),通过哈希(Hash),而不是排序来快速操作元素,使得效率更高。由于无序容

2021-01-05 14:38:04 110

原创 深入理解C++11(三)(摘录)

深入理解C++11(三)列表初始化为了统一初始化方式,并且让初始化行为具有确定的效果,C++11中提出了列表初始化(List-initialization)的概念。1.3.1 统一的初始化在上面我们已经看到了,对于普通数组和POD类型,C++98/03可以使用初始化列表(initializer list)进行初始化:int i_arr[3] = { 1, 2, 3 };long l_arr[] = { 1, 3, 2, 4 };struct A{int x;int y;} a = {

2021-01-05 14:15:45 274

原创 深入理解C++11(十五)

深入理解C++11(十五)emplace_back减少内存拷贝和移动emplace_back能就地通过参数构造对象,不需要拷贝或者移动内存,相比push_back能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升。在大多数情况下应该优先使用emplace_back来代替push_back。所有的标准库容器(array除外,因为它的长度不可改变,不能插入元素)都增加了类似的方法:emplace、emplace_hint、emplace_front、emplace_after和emplace_

2021-01-04 21:42:45 95

原创 深入理解C++11(十四)

深入理解C++11(十四)forward和完美转发右值引用类型是独立于值的,一个右值引用参数作为函数的形参,在函数内部再转发该参数的时候它已经变成一个左值了,并不是它原来的类型了。比如:template <typename T>void forwardValue(T& val){processValue(val); // 右值参数会变成左值}template <typename T>void forwardValue(const T& val){

2021-01-04 21:23:25 183 1

原创 深入理解C++11(九)

深入理解C++11(九)move语义我们知道移动语义是通过右值引用来匹配临时值的,那么,普通的左值是否也能借助移动语义来优化性能呢,那该怎么做呢?事实上C++11为了解决这个问题,提供了std::move方法来将左值转换为右值,从而方便应用移动语义。move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝。深拷贝和move的区别如图2-1所示。copy和move区别...

2021-01-04 20:59:12 314 1

原创 深入理解C++11(十二)

深入理解C++11(十二)改进对象池模式对象池对于创建开销比较大的对象来说很有意义,为了避免重复创建开销比较大的对象,可以通过对象池来优化。对象池的思路比较简单,事先创建好一批对象,放到一个集合中,每当程序需要新的对象时,就从对象池中获取,程序用完该对象后都会把该对象归还给对象池。这样会避免重复创建对象,提高程序性能。对象池的实现如代码清单8-12所示。#include<string>#include<functional>#include<memory>#i

2020-12-31 10:30:15 126

原创 对象池模式(摘录)

对象池模式(摘录)原文1: 对象池模式 C++实现.原文2: C++对象池的实现和原理.对象池模式对象池是一种对象复用技术。Mark Grand在《Patterns in Java》描述了对象池的设计模式,它通过管理和复用有限对象来共享某些稀少或必须付出昂贵代价的资源,该模式的UML结构分为3部分。Reusable:被复用的对象或资源。Client:复用对象的使用者,1个Client对象可以使用多个复用对象,一个复用对象只能同时被1个Client使用。ReusablePool:对象池即

2020-12-31 09:58:28 140

原创 深入理解C++11(六)

深入理解C++11(六)lambda表达式lambda表达式是C++11最重要也最常用的一个特性之一。其实在C#3.5中就引入了lambda,Java则至今还没引入,要等到Java 8中才有lambda表达式。lambda来源于函数式编程的概念,也是现代编程语言的一个特点。C++11这次终于把lambda加进来了。lambda表达式有如下优点:·声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,好的可读性和可维护性。·简洁:不需要额外

2020-12-30 09:37:54 111

原创 深入理解C++11(二)

深入理解C++11(二)模板的细节改进C++11改进了编译器的解析规则,尽可能地将多个右尖括号(>)解析成模板参数结束符,方便我们编写模板相关的代码。1.2.1 模板的右尖括号在C++98/03的泛型编程中,模板实例化有一个很烦琐的地方,那就是连续两个右尖括号(>>)会被编译器解释成右移操作符,而不是模板参数表的结束。代码清单1-6 C++98/03中不支持连续两个右尖括号的示例:template <typename T>struct Foo{typedef

2020-12-26 15:02:23 74

原创 深入理解C++11(一)

深入理解C++11(一)类型推导C++11引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能方便地获取复杂的类型,而且还能简化书写,提高编码效率。auto类型推导auto x = 5;// OK: x 是auto pi = new auto(1); // OK: pi 被推导为 int*const auto *v = &x, u = 6; // OK: v 是const int* 类型,u 是const int 类型auto int r; // error: a

2020-12-26 11:00:28 427

原创 详解C++11智能指针

原文:https://www.cnblogs.com/WindSun/p/11444429.html详解C++11智能指针C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用。智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++ 11中最常用的智能指针类型为shared_ptr,它采用引

2020-12-19 16:34:22 128 1

原创 智能指针(二)

智能指针(二)详解智能指针在 Android 的源代码中,经常会看到形如 sp、wp的类型定义,这其实是 Android 中的智能指针。智能指针是 C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。在 C++编程中,有两个很让人头痛的问题:一是忘记释放动态申请的对象从而造成内存泄露;二是对象在一个地方释放后,又在别的地方被使用,从而引起内存访问错误。程序员往往需要花费很大精力进行精心设计,以避免出现这些问题。使用智能指针后,动态申请的内存将会被自动释放(类似 Java 的垃圾回收),

2020-12-19 15:29:01 130 3

原创 智能指针(一)

智能指针(一)sp 和 wp 简析在 Android 系统中,sp 和 wp 称为智能指针(android refbase 类(sp 和 wp))。其实 sp 和 wp 就是 Android 为其 C++实现的自动垃圾回收机制。如果具体到内部实现,sp 和 wp 实际上只是一个实现垃圾回收功能的接口而已,比如说对*,->的重载,是为了使其看起来跟真正的指针一样,而真正实现垃圾回收的是 refbase 这个基类。这部分代码位于如下文件中。/frameworks/base/include/utils

2020-12-19 11:00:26 97 1

原创 Android 的进程通信机制(一)

Android 的进程通信机制(一)在 Android 系统中,每个应用程序都是由 Activity 和 Service 组成的,一般 Service 运行在独立的进程中,而 Activity 有可能运行在同一个进程中,也有可能运行在不同的进程中。那么不在同一个进程的 Activity 或者 Service 之间究竟是如何通信的呢?下面将介绍的 Binder 进程间通信机制来实现这个功能。众所周知,Android 系统是基于 Linux 内核的,而 Linux 内核继承和兼容了丰富的 Unix 系统进程

2020-12-18 19:37:28 459

原创 Android 的内存机制

Android 的内存机制内存是计算机中重要的部件之一,它是与 CPU 进行沟通的桥梁。内存(Memory)也称为内存储器,其作用是用于暂时存放 CPU 中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU 就会把需要运算的数据调到内存中进行运算,当运算完成后,CPU 再将结果传送出来,内存的运行也决定了计算机的稳定运行。内存和进程的关系手机内存的最直接作用体现在进程管理上各种进程的启动、运行和结束都是通过内存实现的。读者需要明白,在 Android中的进程和程序是两回事,程序可

2020-12-18 14:24:42 498

原创 Hal(一)

Hal(一)Android 系统的硬件抽象层(Hardware Abstract Layer,HAL)运行在用户空间中,它向下屏蔽硬件驱动模块的实现细节,向上提供硬件访问服务。通过硬件抽象层,Android 系统分两层来支持硬件 设备,其中一层实现在用户空间中,另一层实现在内核空间中。从现在 HAL 层的结构可以看出,当前的 HAL stub 模式是一种代理人 (proxy)的概念, 虽然 stub仍以“ .so”档的形式存在,但是 HAL 已经将“.so”档隐藏了。Stub 向 HAL 提供了功能强大

2020-12-17 21:19:07 279 1

原创 HIDL(一)(摘录)

原文:https://www.jianshu.com/p/f8e2556499caHIDL(一)定义HAL 接口定义语言(简称 HIDL,发音为“hide-l”)是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。HIDL 允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL 是用于在可以独立编译的代码库之间进行通信的系统。其实HIDL的出现是为了更好的服务于Treble这个项目,由于Android的发展比较迅猛,各大手机厂商和芯片厂商都在做,Googl

2020-12-17 15:55:17 186

原创 MUL图

MUL图1.矩形框(代表类,斜体代表抽象类,+为public,-为private,#为protected)2.接口(顶端有interface标志,或者棒棒糖表示)3.继承(空心三角形表示,箭头指向父类)4.接口实现(空心三角形和虚线表示)5.关联(实线箭头)6.聚合(弱的拥有关系,空心菱形加实箭头)7.组合(强的拥有关系,实心菱形加实箭头)...

2020-12-16 16:39:34 935

原创 C++篇:基础入门(九)

C++篇:基础入门(九)1.内存四区代码区,全局区(static,全局变量,程序结束时销毁),栈区(局部变量,函数结束时销毁),堆区(new分配,由程序员定义分配,并手动销毁)2.引用本质:指针常量引用做函数参数(一般加const 防止修改变量的值);引用做函数返回值;常量引用3.浅拷贝和深拷贝浅拷贝:类里面的默认拷贝构造函数深拷贝: 复写拷贝构造函数,为需要开辟堆空间的变量提供新的堆区变量(防止多个指针指向同一堆区,导致析构函数里重复释放内存)4.初始化列表5.静态成员变量的所有对象共

2020-12-15 20:38:51 68

原创 C++设计模式(二)(摘录)

C++设计模式(二)(摘录)装饰模式装饰模式:动态地给一个对象添加一些额外的功能,它是通过创建一个包装对象,也就是装饰来包裹真实的对象。新增加功能来说,装饰器模式比生产子类更加灵活。以下情形考虑使用装饰模式:需要扩展一个类的功能,或给一个类添加附加职责。需要动态的给一个对象添加功能,这些功能可以再动态的撤销。需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的

2020-12-12 10:11:23 242

原创 C++设计模式(一)(摘录)

C++设计模式享元模式所谓享元模式是指运用共享技术有效地支持大量细粒度的对象。在有大量对象时,把其中共同的部分抽象出来,如果有相同的业务请求,直接返回内存中已有的对象,避免重新创建。享元模式的优点:1.它可以极大减少内存中对象的数量,使得相同对象和相似对象在内存中只存在一份。2.享元模式的外部状态相对独立,而且不会影响其内部状态,从而使享元对象可以在不同的环境中被共享。享元模式的缺点:1.享元模式时的系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。2.为了使对象可以

2020-12-10 10:11:39 74

原创 C++篇:基础入门(七)

C++篇:基础入门(七)C++ 信号处理信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 中。signal() 函数C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:void (*signal (int sig, v

2020-12-09 17:23:16 80

原创 C++篇:基础入门(六)

C++篇:基础入门(六)C++ 模板模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector 或 vector 。您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。模板函数定义的一般形式如下所示:template <typename type> ret-type f

2020-12-09 16:42:49 192

原创 C++篇:基础入门(五)

C++篇:基础入门(五)动态内存了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分:栈:在函数内部声明的所有变量都将占用栈内存。堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。如果您不再

2020-12-09 16:03:07 58

原创 C++篇:基础入门(四)

C++篇:基础入门(四)数据抽象数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。数据抽象是一种依赖于接口和实现分离的编程(设计)技术。让我们举一个现实生活中的真实例子,比如一台电视机,您可以打开和关闭、切换频道、调整音量、添加外部组件(如喇叭、录像机、DVD 播放器),但是您不知道它的内部实现细节,也就是说,您并不知道它是如何通过缆线接收信号,如何转换信号,并最终显示在屏幕上。因此,我们可以说电视把它的内部实现和外部接口分离开了,您无需知道它的内部实现原理,

2020-12-09 14:51:55 133

原创 C++篇:基础入门(三)

C++篇:基础入门(三)类和数据抽象类定义了数据成员和函数成员:数据成员用于存储与该类类型的对象相关联的状态,而函数成员则负责执行赋予数据意义的操作。通过类我们能够将实现和接口分离,用接口指定类所支持的操作,而实现的细节只需类的实现者了解或关心。这种分离可以减少使编程冗长乏味和容易出错的那些繁琐工作。从第一章开始,程序中就已经使用了类。已经用过的标准库类型,比如vector,istream 和 string,都是类类型。还定义了一些简单的类,如Sales_item 和 TextQuery 类。为了扼要

2020-12-08 19:56:57 366

原创 ROS:机器人软件平台(一)

ROS:机器人软件平台(一)导论ROS简介“ROS是一个开放源代码的机器人元操作系统。它提供了我们对操作系统期望的服务,包括硬件抽象、低级设备控制、常用功能的实现、进程之间的消息传递以及功能包管理。它还提供了用于在多台计算机之间获取、构建、编写和运行代码的工具和库。”换句话说,ROS包括一个类似于操作系统的硬件抽象,但它不是一个传统的操作系统,它具有可用于异构硬件的特性。此外,它是一个机器人软件平台,提供了专门为机器人开发应用程序的各种开发环境。我们为什么要学习ROS这个新的概念?这是在线下的RO

2020-12-07 23:06:34 2151 1

原创 C++篇:基础入门(二)

C++篇:基础入门(二)在类外定义成员函数在类的定义外面定义成员函数必须指明它们是类的成员:double Sales_item::avg_price() const{if (units_sold)return revenue/units_sold;elsereturn 0;}形参表后面的 const 则反映了在类 Sales_item 中声明成员函数的形式。在任何函数定义中,返回类型和形参表必须和函数声明(如果有的话)一致。对于成员函数,函数声明必须与其定义一致。如果函数被声明为

2020-12-07 21:06:39 61

原创 C++篇:基础入门

C++篇:基础入门string 对象的操作s.empty() :如果 s 为空串,则返回 true,否则返回 false。s.size() : 返回 s 中字符的个数s[n] : 返回 s 中位置为 n 的字符,位置从 0 开始计数s1 + s2 : 把 s1 和 s2 连接成一个新字符串,返回新生成的字符串s1 = s2 : 把 s1 内容替换为 s2 的副本v1 == v2 : 比较 v1 与 v2 的内容,相等则返回 true,否则返回 false!=, <, <

2020-12-07 14:53:31 3937

原创 驱动篇:底层驱动移植(四)(摘录)

驱动篇:底层驱动移植(四)(摘录)时钟驱动在一个 SoC 中,晶振、 PLL 、驱动和门等会形成一个时钟树形结构,在 Linux 2.6 中,也存有clk_get_rate ()、clk_set_rate ()、 clk_get_parent ()、 clk_set_parent ()等通用 API ,但是这些 API 由每个 SoC 单独实现,而且各个 SoC 供应商在实现方面的差异很大,于是内核增加了一个新的通用时钟框架以解决这个碎片化问题。之所以称为通用时钟,是因为这个通用主要体现在:1 )统一

2020-12-05 16:55:18 551

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除