- 博客(94)
- 收藏
- 关注
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 C++基础笔记
32位系统不管是什么类型的指针,占用的内存都是4字节,寻址范围就是2的32次方,有4294967296个内存地址,4294967296个地址X8位空间=34359738368bit(位)/8=4294967296Byte/1024=4194304KB/1024=4096MB/1024=4G。是可能,不是一定,程序的表现是不稳定,增加了调试程序的难度。在C++11中,赋予了auto全新的含义,不再用于修饰变量,而是作为一个类型指示符,指示编译器在编译时推导auto声明的变量的数据类型。
2017-11-20 10:54:32
453
原创 文件操作与IO多路复用.md
select是通过描述符位图的方式监视文件描述符集合的可读写状态。调用select会阻塞直到有描述符就绪或超时,监视这些描述符,返回就绪的描述符集合。poll使用链表的数据结构监视描述符集合,可以更高效地监视大数量的描述符。epoll使用一个epoll实例来管理多个文件描述符,而不是直接操作文件描述符集合。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。C++中的输入输出都是建立在流的概念之上的。在上面的示例中,我们使用。
2023-08-10 11:21:03
190
原创 M1 mac 直接安装x86 centos Docker
您可以添加 --platform linux/amd64 以在仿真下运行英特尔映像.因为Docker默认创建的是arm架构的CentOS,如果没有指定为amd64,将无法执行yum install glibc-devel.i686,gcc -m32等命令,在我的 M1 Mac 上,我可以从 Docker Hub 运行 Ubuntu 映像的 arm64 和 amd64 版本。将镜像从 mirror.centos.org 更改为 vault.centos.org。安装常用软件 vim make 库等。
2023-05-28 18:03:01
2572
原创 M1 PD安装arm ubuntu及Docker
在卸载 Docker 之前,你最好 移除所有的容器,镜像,卷和网络。删除现有的docker安装并添加docker的官方GPG密钥。下载 Ubuntu 22.04.2 LTS。添加docker的软件源。
2023-05-28 17:55:31
1100
原创 安卓启动与镜像刷机
在AOSP系统中,/vendor分区用于存放设备厂商提供的二进制文件和资源。根文件系统镜像通常会包含大部分系统所需要的二进制程序和文件,但不一定会包含所有的bin程序。Android Boot Loader,简称ABL,是Android设备的第一阶段引导程序。gcc编译后的程序默认使用ELF格式,所以我们可以说ELF格式是gcc生成程序的常用格式之一。在Android系统中,大多数重要分区都会设置主备分区,用于实现备份与恢复的功能。userdata - 存储用户数据,如应用数据、下载的文件等。
2023-05-27 00:22:29
4385
2
原创 Rust SmartPointer
Rust的所有权(ownership)和智能指针(smart pointers)是它的两个重要特征。理解它们是掌握Rust特性和编写Rust程序的基础。理解所有权与智能指针的工作方式,可以让我们编写无bug,高效,优雅的Rust代码。它们是Rust的核心概念,是学习和掌握Rust的基石。Rust禁止在没有所有权的情况下使用值,这可以有效地防止“双乘出错”等问题。智能指针是封装了原始指针的结构体,可以轻松实现自动内存管理。:用于“钉住”数据的智能指针,防止被move。8. Cow:拥有或借用值的智能指针。
2023-05-21 17:23:33
642
原创 Why Rust Android
但是,初始化为零并不总是安全的,特别是对于返回值之类的内容,这可能成为错误处理的新来源。是的,Rust 通过静态分析可以在编译期就识别和消除数据竞争,这确保了其程序在多线程环境下的并发安全,这也是Rust被称为"无畏并发"的原因之一。所以,通过编译器严密的检查,Rust可以在编写时就识别和消除各种内存错误,这确保了其程序在运行时的内存安全,这是其最重要的优点之一。总之,Rust的所有权系统、借用检查和RAII可以在编译期和运行时确保内存安全和数据竞争的不存在,这使其成为一门真正的无畏并发语言。
2023-05-21 17:22:09
597
原创 linux 系统启动基础
它是Linux下常用的二进制文件格式,用于存储可执行文件、目标文件、动态链接库及调试符号信息等。在AOSP系统中,/vendor分区用于存放设备厂商提供的二进制文件和资源。根文件系统镜像通常会包含大部分系统所需要的二进制程序和文件,但不一定会包含所有的bin程序。Android Boot Loader,简称ABL,是Android设备的第一阶段引导程序。gcc编译后的程序默认使用ELF格式,所以我们可以说ELF格式是gcc生成程序的常用格式之一。
2023-04-27 17:53:29
780
1
翻译 Android.bp和Androd.mk区别以及宏变量对应关系
Android.bp的出现就是为了替换Android.mk文件。旧的mk可以转换为bp,Soong会编译生成一个androidmk命令,用于将Android.mk文件转换为Android.bp文件。用 androidmk 将 Android.mk 生成为 Android.bp , 但是bp是无法条件编译的, 如果里面有条件编译 你可能需要修改你的 Android.mk。这个是找不到应用的模块, 原因是模块是用 Android.mk 构建编译的,而我编译的测试模块是 Android.bp 构建的。
2023-03-17 15:13:23
312
转载 linux selinux基础
背景:安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。SELinux 主要由美国国家安全局开发。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。
2023-02-21 11:06:03
436
翻译 MCU_MPU开发
(里面有负责处理指令的cpu(也可以是dsp或者gpu),负责跑程序的ram和负责存数据的rom.由这三大件和其他的外部接口(像内存、计数器、USB、A/D转换、UART、PLC、DMA等)组成,就是微型计算机),MCU实现功能靠的是外围的一些硬件接口。目前的MCU和MPU的界限在逐渐模糊,MCU的主频也在不断提高,外设不断增加。与板上系统相比, SoC 的解决方案成本更低,能在不同的系统单元之间实现更快更安全的数据传输,具有更高的整体系统速度、更低的功耗、更小的物理尺寸和更好的可靠性。
2023-02-08 15:58:56
623
原创 计算机的大小端存储
内存地址存储的最小数据大小就是字节,例如一个变量char temp的地址0x10000000,temp值为0x55,由于char类型只占用一个字节,那么temp变量就只占用0x10000000这个内存地址,不会占用其他内存地址,那假如变量是个int型呢?这里有几个概念:高地址,低地址,高位,低位,其中高地址,低地址是针对内存地址而言,高位,低位是针对数据类型的bit位的高低而言。当基本数据类型占用字节数超过了1字节后,大小端决定了数据按照什么顺序存储在内存里。大小端只针对基本数据类型。
2023-02-01 11:49:55
171
转载 C++多态虚函数表内存布局
假设有一个基类ClassA,一个继承了该基类的派生类ClassB,并且基类中有虚函数,派生类实现了基类的虚函数。我们在代码中运用多态这个特性时,通常以两种方式起手:(1) ClassA *a = new ClassB();(2) ClassB b; ClassA *a = &b;以上两种方式都是用基类指针去指向一个派生类实例,区别在于第1个用了new关键字而分配在堆上,第2个分配在栈上。请看上图,不同两种方式起手仅仅影响了派生类对象实例存在的位置。...
2022-07-08 10:56:53
696
翻译 c++构造函数的使用
对于一般的类来说,如果不声明构造函数,则自动调用默认构造函数class A{public:A();};如果声明了另外一个构造函数,则会覆盖默认构造函数class A{public:A(int n){a=n};private:int a;};此时如果声明一个对象,则不可以直接A a;必须要A a(3);多数情况下,编译器为类生成一个默认构造函数,只有以下两种情况除外:一个类显式地声明了任何构造函数,编译器不再生成默认构造函数,除非设计者也显式声明了默认构造函数cl
2022-07-07 23:02:49
458
转载 c++ 11 lambda 用法与原理
lambda也出现了好长时间,一直以来也仅仅限于使用,今天,借助此文,我们从使用、实现的角度聊聊lambda。在开始正文之前,我们先看一个问题,对下面的vector进行排序:std::vector<int>v={1,3,2};在C++11之前,我们可能会这么做(普通函数,即函数指针作为参数):boolCompare(inta,intb){returna<b;}intmain(){std::vector<int>...
2022-05-27 22:21:22
1001
翻译 c++ 线程池
// 线程池线程个数缺省值#include <iostream>#include <vector>#include <queue>#include <unistd.h>using namespace std;const size_t NUM = 5;template <class T>class ThreadPool{public: // 构造函数,负责初始化成员变量和创建线程 ThreadPool(const siz
2022-05-26 21:45:08
109
翻译 c++ 11类型转化
C/C++是强类型语言,不同类型之间的相互转换是比较麻烦的.但是在编程实践中,不可避免的要用到类型转换.类型转换:隐式类型转换强制类型转换隐式类型转换提升精度,此种是编译器自动完成的,安全的.所以编译的时候不会有任何错误或者警告信息提示.示例:int ival = 3;double dval = 3.14159;// ival 被提升为 double 类型: 3.0ival + dval;降低精度,也是有编译器自动完成,会造成精度丢失,所以编译时得到一个警告信息提示.
2022-05-25 22:25:11
1581
转载 linux 驱动
驱动认知1. 什么是驱动驱动就是对底层硬件设备的操作进行封装,并向上层提供函数接口。设备分类:linux系统将设备分为3类:字符设备、块设备、网络设备。 字符设备:指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等,字符设备驱动程序通常至少要实现open、close、read和write的系统调用,字符终端(/dev/console)和串口(/dev/ttyS0
2022-05-25 21:29:28
4879
翻译 c++ 右值引用 与std:move
左值与右值通常来说你确实可以使用一个值在表达式中的位置信息来判断这个值的左右值类型,比如说在下面这段代码中:int x = 10;int y = 20;int sum = x + y;最后一行当中,位于 " = " 左侧的sum就是一个左值,而右侧的 " x + y " 就是一个右值。除此之外,还可以用另外一种常用的方式来判断:可以取地址的,有名字的就是左值反之不能取地址,没有名字的就是右值比如在刚刚的代码的最后一行中,我们就可以对sum进行取地址操作,而不能对等号右侧的x+y进行取地址
2022-05-25 21:03:18
392
翻译 c++深浅复制
浅复制缺省复制构造函数:用一个对象的内容初始化另一个同类对象,也称为缺省的按成员拷贝,不是对整个类对象的按位拷贝。这种复制称为浅复制。”浅复制可能带来什么问题“class CGoods{ char *Name; //不同与char Name[21] ? int Amount; float Price; float Total_value; public:&
2022-05-25 20:55:21
175
翻译 c++ template
泛型初步由于C++是静态强类型语言,所以变量一经创建,则类型不得更改。如果我们希望创建一种应用广泛地复数类型,那么相应地需要基于int、float、double这些基础类型逐一创建,十分麻烦。泛型编程便是为了简化这一过程而生。能够容纳不同数据类型作为成员的类被成为模板类,其基本方法为在类声明的上面加上一行模板声明代码template<typename T>class myClass{};其调用过程为myClass<T> m;列举案例如下#include<iost
2022-05-25 20:53:34
102
转载 rust lifetime
Rust 生命周期首先每个引用都有生命周期,也就是引用保持有效的作用域一个引用的作用域从声明的地方开始一直持续到最后一次使用为止let a=String::from("a");let b=&a;//b的诞生 ,后续没有在使用b,所以b死亡在借用者生命期间,所有者必须是活的,不然就会产生悬垂引用,幸运的是我们不用关注它,交给编译器来提示,编译器通过生命周期来检查大部分时候生命周期是隐含并可以推断的,但有些情况就无法推断了,需要程序员自己指出fn longest(x: &Stri
2022-04-17 16:32:36
140
转载 rust send sync 理解
关于Sync和Send的含义sync 想要一个类型的同一个变量可以在不同线程同时拥有它的不可变引用,则必须实现Syncsend 想要一个类型可以在线程之间移动,则必须实现Sendsend 表示跨线程move,sync表示跨线程share data,两者基本就是ownership和borrow的区别如果一个类型可以安全地传递给另一个线程,这个类型是 Send如果一个类型可以安全地被多个线程共享 (也就是 &T 是 Send),这个类型是 SyncSend 和 Sync 是
2022-04-17 16:23:13
1079
1
转载 协程:快速地实现高并发服务
零拷贝通过减少上下文切换次数,提升了文件传输的性能。事实上高并发服务也是通过降低切换成本实现的。如果你需要访问多个服务来完成一个请求的处理,比如实现文件上传功能时,首先访问 Redis 缓存,验证用户是否登陆,再接收 HTTP 消息中的 body 并保存在磁盘上,最后把文件路径等信息写入 MySQL 数据库中,你会怎么做?用阻塞API写同步代码最简单,但一个线程同一时间只能处理一个请求,有限的线程数导致无法实现万级别的并发连接,过多的线程切换也抢走了 CPU 的时间,从而降低了每秒能够处理的...
2022-04-17 14:27:48
687
翻译 同步模型(synchronous IO)IO多路复用
同步模型(synchronous IO)IO多路复用网络应用需要处理的无非就是两大类问题,网络IO,数据计算。相对于后者,网络IO的延迟,给应用带来的性能瓶颈大于后者。网络IO的模型大致有如下几种:1: 同步模型(synchronous IO)阻塞IO(bloking IO)非阻塞IO(non-blocking IO)多路复用IO(multiplexing IO)信号驱动式IO(signal-driven IO)2: 异步IO(asynchronous IO)相对于同步IO,异步IO不是顺序执
2022-04-16 15:38:17
460
原创 tokio mpsc channel
预期行为是:要求用户随机输入(q退出)将相同的输入打印到标准输出将std::io::stdin()替换为tokio::io::stdin()还需要将标准库BufReader替换为tokio的实现,该实现封装了R: AsyncRead而不是R: Read。为了防止输入任务和输出任务之间的交叉写入,可以使用一个响应器通道,在输出已打印时向输入任务发送信号。use std::error::Error;use tokio::io::{AsyncBufReadExt, AsyncWriteExt};us
2022-04-14 15:01:58
452
翻译 Rust async/await && Tokio
Rust的async/await特性是通过一种称为协作式调度(cooperative scheduling)的机制来实现的,这对于编写异步Rust代码的人来说有一些重要的影响。这篇博文的目标读者是异步Rust的新用户。我将使用Tokio运行时作为示例,但这里提出的观点适用于任何异步运行时。如果你只从这篇文章中记住一件事,那应该是:异步代码不应该长时间不到达.await。(注:指的是运行中)Blocking vs. non-blocking code编写一个可以同时处理许多事情的..
2022-04-14 14:47:02
1108
翻译 C++多线程同步
摘要:本文介绍了C++11中如何开启新线程,并详细讲解了线程的基础同步原语:mutex, lock_guard, unique_lock, condition variable和semaphore等。如何采用async, packaged_task和promise实现future同步机制?怎样处理spurious wakeup?本文以质数判定服务为例为大家分享C++多线程同步措施!1. C++线程和基础同步原语Thread mutex, lock_guard, unique_lock con.
2022-03-22 23:19:16
5137
1
原创 C++锁总结
锁:mutexmutex 独占的互斥量,不能递归使用 C++11timed_mutex 有超时功能的独占互斥量,不能递归使用 C++11recursive_mutex 递归互斥量,能递归使用 C++11recursive_timed_mutex 有超时功能的递归互斥量 C++11shared_timed_mutex 具有超时机制的可共享互斥量 C++14shared_mutex 共享的互斥量 C++17读写锁(std::shared_mutex)读写锁相比互斥锁,读写锁允许更高的并..
2022-03-22 23:12:59
3504
1
原创 IPC进程线程
进程进程:进程是指一个具有独立功能的程序在某个数据集合上的一次动态执行过程,是操作系统及进行资源分配和调度的基本单位。注意:一次任务的运行可以激活多个进程。进程是一个程序的执行的过程,是动态的,包括程序的创建、调度、消亡进程具有并发性、动态性、交互性、独立性等主要特性1.并发性:指的是系统中多个进程可以同时并发执行,相互之间不受干扰。——马路上两个汽车各跑各的,互不影响2.动态性:指的是进程都有完整的生命周期,而且在进程的生命周期内,进程的状态时不断变化的,进程具有动态的地址空间3.交互
2022-03-21 23:36:50
356
原创 设计模式(3)-行为模式
行为型模式,共十一种:模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。我们的例子中,操作就是填写简历这一过程,我们可以在父类中定义操作的算法骨架,而具体的实现由子类完成。//简历 class Resume { protected: //保护成员 virtual void SetPersonalInfo() {} virtual void SetEducation() {}.
2022-03-21 00:14:51
314
原创 设计模式(2)-结构型模式
结构型模式,共七种:外观(门面)模式外观模式应该是用的很多的一种模式,特别是当一个系统很复杂时,系统提供给客户的是一个简单的对外接口,而把里面复杂的结构都封装了起来。隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。属于结构型模式。这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。#include<iostream>using namespace std;//创建一个形状的抽象接口shapeclass shape{p.
2022-03-20 23:20:47
291
原创 设计模式(1)-创建型
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:单例模式单例模式顾名思义,就是在系统中只允许产生这个类的一个实例。实例说明:很多大臣拜见的皇帝,只有一个。体现在面向对象方面,CEmperor定义一个静态指针,和一个静态函数,私有化构造函数、析构函数、构造函数复制、重载赋值语句。注意:线程安全,采用互斥体的方式实现用单例的方式实现Emperor,不论在使用过程中new多少次均只会有一个实例//Emperor.h#pragma once#include &
2022-03-20 23:19:41
391
原创 数据结构及算法
数据结构与算法算法数学领域里,算法是用于解决某一类问题的公式和思想。计算机科学领域的算法,它的本质是一系列程序指令,用于解决特定的运算和逻辑问题。衡量算法好坏的重要标准有两个。时间复杂度时间复杂度是对一个算法运行时间长短的量度,用大O 表示,记作T (n )=O (f (n ))。常见的时间复杂度按照从低到高的顺序,包括O (1)、O (logn )、O (n )、O (n logn )、O (n 2 )等。空间复杂度空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,
2022-03-20 14:52:16
439
原创 现代c++ (3)
智能指针类引入:C/C++最为人诟病的是内存泄露问题,后来的大多数语言都内置了内存分配与释放功能,有的甚至对语言的使用者屏蔽了内存指针这一概念。这里对此不置褒贬,手动分配与释放内存有利有弊,自动分配与释放内存亦如此,这是两种不同的设计哲学。有人认为,内存如此重要,怎能放心将其交给用户去管理呢?另外一些人则认为,内存如此重要,怎能放心将其交给系统去管理呢?在C/C++中,内存泄露的问题一直困扰着广大开发者,因此各类库和工具也一直在努力尝试各种方法去检测和避免内存泄露,例如 boost,因此智能指针技术应
2022-03-20 13:54:40
697
原创 现代c++(2)
现代c++ 新特性C++11标准中,我们可以使用花括号(即{})对任意类型的变量,无论是局部变量还是类变量进行初始化,而且不用是static类型。*统一的类成员初始化语法 std::initializer_listenumerator enum class Color{ black, white, yellow }由于枚举值white对外部不可见(必须通过Color::white引用),所以可以定义一个同名的white变量。这种枚举变量被称为限定
2022-03-20 00:33:34
762
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人