自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 说说gyp,再也不用手撸Makefile

Warming up简要说说 gcc 的过程:预处理:主要处理头文件的包含以及宏替换编译:将高级语言编译成汇编语言汇编:将汇编语言转换成机器指令,此时得到目标文件链接:目标文件库文件的链接,最终得到可执行文件一些有用的选项: -E 进行预处理,注意,该命令会将结果输出到控制台上,我们要输出到文件里面。gcc -E ***.c -o xxx.i: -S 编译, gcc -S xxx.i, 得到 xxx.s 文件: -c 汇编处理, 生成目标文件 xxx.o 文件其他选项: -std

2020-08-04 22:46:08 1646

原创 闲话一篇说说什么是光刻机

曾经就职于一家中国人自己的光刻机研发制造公司,不是研发不是技术,而是QA岗位,由于对技术比较喜欢,反而从更加系统的层面,了解了一下,什么是光刻机。什么是光刻机俗称印钞机,真的是印钞机。想想看,沙子,即便是石英砂吧,进去了,出来个芯片,进去个玻璃,出来个液晶屏幕,这不就是典型的点石成金吗?其他地方的人管钱叫钱,而上海方言的择词,钱叫钞票,钱包,叫皮夹子。光刻机就是合法的没日没夜的印钞票啊。想当年,那些技术,天天用中国的航天去鼓励,要求自己,其实,看着那些研发,能看出来他们自己对自己都没什么信心。那个时

2020-07-26 15:43:37 2453 1

原创 基于socket以及C++实现的单进程多线程HTTP服务平台On Linux Platform

思路底层,网络通讯层:采用epoll+non-block socket 进行多路复用。采用redis的event loop框架,稍作修改。这一层干嘛呢,就干一件事儿,监听,然后处理链接上来的socket,读取请求数据数据。这个地方,我现在有另外一个想法,两种方式去实现:第一种,主线程去 accpet,epollwait client fd 的连接,连接上来之后,读取数据的工作,是不是放到IO Trans thread 中去处理。这个新链接上来的clientfd 我们将其挂载到 io thread

2020-07-21 23:31:54 355

原创 基于C++ std::thread 的线程池

设计思路算了,直接上代码,自己看吧。/******************************************************* * @FileName: Task.h * @Author: Frodo Cheng * @CreatedTime: Jul 17th 2020 * @Description: * Wrapped thread pool task.********************************************************

2020-07-17 20:00:12 1136

原创 自实现C语言的内存池

前言具体什么是内存池,不说了。我也是闲来无聊,自己实现一个内存池,也比较简单。设计思路我们采用C语言实现,所以,需要实现一些简单的容器。比如单链表。总体大概设计思路示意图如上所示。一个数组(或者向量(我们把原始的C语言数组,称之为数组,把类似的在堆空间中申请来的连续线线性空间称之为向量)),每一个节点是一个链表,每个链表里面挂着元素,元素的data指针便是我们内存池里面放的内存指针。详细思路第一:纲领数组我们按照索引,最小比如64,128,256 这样预先定义好。到了足够大之后,比如4k,我

2020-07-12 20:20:31 538

原创 Node js 非线程/进程安全的 较为高效的简单可用的日志模块

日志实现模块#! /usr/bin/env node/*********************************************** * @Author: Frodo Cheng * @Time: 2020-07-10 15:55:00***********************************************/let fs = require('fs');let os = require('os');let process = require('pro

2020-07-10 16:56:51 166

原创 mediasoup v3 API 之三 Producer Consumer & RtpObserver

ProducerProducerOptionsFieldTypeDescriptionRequiredDefaultkindMediaKind媒体类型audio或者videoYesrtpParametersRtpSendParameters发送端的rtp参数,produce出来的类型YespausedBooleanstart之后,end端,建议先pause,等待resume,建议给true,后续跟进需要resumeNofalsekeyF

2020-07-10 13:31:44 1180

原创 mediasoup v3 API 之二 Transport

WebRtcTransportMediasoup 内部有多种 Transport 实现,其中 WebRtcTransport 的实现是基于 ICE Lite(精简版ICE)。WebRtcTransport 主要用来进行 client 端 与 mediasoup server 端 Router 进行通讯。ICE Lite: meaning that it does not initiate ICE connections but expects ICE Binding Requests from en

2020-07-10 13:31:05 2166

原创 mediasoup v3 API 学习之一

mediasoup 模块的一些属性mediasoup.typesmediasoup 模块对外 export 出来的所有的 class + TypeScript 语法定义的类型。var ms = require('mediasoup');console.log(ms.types);结果如下:{ Worker: [Function: Worker], Router: [Function: Router], Transport: [Function: Transport], WebR

2020-07-10 13:30:26 2163

原创 Mediasoup Overview

Mediasoup Overview官方 mediasoup 英文文档非官方 mediasoup 中文文档暂无中文文档mediasoup 是一个基于 C++ 实现具有 SFU 的功能库,其 server 端对外提供 Nodejs API。mediasoup 自身并不提供任何信令协议。所以需要应用程序,来确认 mediasoup 客户端与服务端进行通信的方式,用来协商客户端与服务端的相关参数和信息。在大多数情况下,此通信必须是双向的,因此通常需要全双工信道(如 TCP 或 SCTP

2020-07-10 13:29:20 727

原创 MediaSoup MediaSoup-demo v3 版本部署测试

环境系统软件源http://mirrors.aliyun.com/ 阿里云NodeJS 与 npm 版本npm 源GCC 版本准备过程安装 nodejs 以及 npmsudo apt install nodejssudo apt install npmsudo npm install -g npm // 强制更新 nodejs 版本。替换 npm 源sudo npm config set registry https://registry.

2020-07-04 03:05:04 2804 6

原创 Linux Kernel 网络 之 Netlink

参考书籍《精通Linux内核网络》 Rami Rosen著(罗伊森)Netlink 也是一种套接字,就是socket,跟TCP/UDP的socket是类似的,但是,不同的是,TCP/UDP层的socket是 BSD socket。Netlink是独立的一套协议族。作用这是该参考书中的说明,这段说明,真是扯淡,对于没有从事过内核网络开发的人来说,这简直是天书。说白了,这也是一种通信协议,不同的是,一般所说的通信协议,指的是不同主机,包括网络设备之间的通信,可以是有线,也可以是无..

2020-06-23 21:52:34 1376

原创 Linux Kernel Driver I2C 总线驱动编程

概念I2C 总线,为两线式串行总线。CPU与外设之间的数据通信采用两根信号线分别是:SDA数据线以及SCL时钟控制信号线。SDA:用于CPU与外设的数据传输。SCL:用于同步双方的数据。CPU在SCL为低电平时,将数据放在数据线上,那么设备在同周期的高电平,从数据线上获取数据。串行:CPU和外设之间的数据通信是一个时钟周期传输一位。总线:在SCL和SDA两根信号线上可以挂接多个外设。示意图,如下:上拉电阻:两个信号线,各界上一个上拉电阻,两根线默认都是高电平。

2020-06-20 15:59:55 862

原创 Linux Kernel Driver 分离模型示例

类型定义// hello_def.h#ifndef __HELLO_DEF_H__#define __HELLO_DEF_H__#define HELLO_OPEN (0X10001001U)#define HELLO_CLOSE (0X10001002U)#define HELLO_INFO (0X10001003U)// 声明描述 hello 硬件相关的数据结构(自定义硬件信息)struct hello_resource{ int phys_

2020-06-19 17:22:46 191

原创 Linux Kernel Driver 之 混杂设备 ioctl 以及一些补充示例

misc 混杂设备混杂设备,本质上还是字符设备。其主设备号固定为 10,次设备号作为各个混杂设备的区分的依据。minor 一般使用 MISC_DYNAMIC_MINOR 即可。name 即设备文件,也即 /dev/ 目录下的 hello 文件。fops 与前文的 fops 意义相同。misc 对象的定义与初始化如下:注册以及卸载混杂设备。注册时,无需手动mknod 创建设备文件,注册API 会同时创建对应的name域的文件。代码#include <

2020-06-19 12:13:11 488

原创 Linux Kernel Driver 之 mmap 机制 Linux 内核编程的分离思想

前言Linux 编程中,大多数的场景,数据的交换,不论读还是写都要经过两次数据拷贝过程:用户和内核,内核和硬件物理内存如果数据的访问量比较小,两次的数据拷贝对系统性能影响几乎可以忽略不计如果数据的访问比较大,两次的数据拷贝势必影响系统性能数据的操作的规律是源要不是用户或者硬件,目的要不是硬件或者用户,而内核仅仅作为一个缓冲,所以用户到内核的数据拷贝是多余的,如果让用户在用户空间访问硬件设备的物理内存,即可将两次数据拷贝变成一次数据拷贝以下设备的数据量的访问比较大:摄像头,声卡,显卡,LC

2020-06-16 18:02:42 1081

原创 Linux Kernel Driver 之 阻塞,内存访问以及所谓上下文的补充说明

Linux 内核的阻塞阻塞亦即等待,有两种,一种忙等待,一种休眠等待。应用层阻塞,多数是指休眠等待。阻塞的实现,一般都是基于等待队列机制。非阻塞:事件如果得不到满足,不会休眠等待,而是立即返回到用户空间。Linux 系统默认的实现是阻塞方式,但是,linux系统也要求,驱动编程必须支持非阻塞方式的实现。那么,阻塞,我们可以利用等待队列完成,那么非阻塞的方式呢?非阻塞的实现应用层,用户空间需要显式操作。可以在open时给定 O_NONBLOCK,或者,调用fcntl 函数设置。

2020-06-16 14:01:36 397

原创 Linux Kernel Driver 之 解决竞态之 原子操作以及 Linux 内核 之 等待队列

Linux 竞态解决方案之原子操作原子操作可以解决任何情况下的竞态问题。Linux的原子操作主要分为位原子操作以及整型原子操作位原子操作egint g_data = 0x10; // 共享资源g_data |= (1<< 3);g_data ~= ( 1>>2);以上的两个位操作并不是原子操作。如果内核编程中,操作共享资源时,需要解决竞态问题,除了之前博客中所说的那三种方法,原子操作也是一个很好的方案。内核也提供了一些位原子操作的API,如下:

2020-06-16 11:57:13 228

原创 Linux Kernel Driver 字符设备 之 自动创建节点

前言之前的实验,都是 mknod 手动创建节点,确实比较麻烦。如何自动创建节点呢?如果是pc机,比较高级的用的如果是udev 那么比较简单,如果是嵌入式系统被才裁减了,用mdev 相对复杂一些。之前,如果做过,mknod 创建过的,需要删除掉,rm -rf /dev/hellomkdev1.保证根文件系统支持mdev可执行程序which is mdev如果没有,那就不支持了,然后 which is udevadm,如果有机制udev,那就不需要往下走了。2. 保证文...

2020-06-15 21:22:13 471

原创 Linux Kernel Driver 字符设备驱动 续

前文hello 字符设备已经完成了open以及close的操作,但是第一,不能读写第二,并发不安全读写我们这是字符设备,但是是假的,没有硬件支持,所以,我们写进来的东西,还要能读出去, 我们最好还能简单处理一下,模拟一下硬件设备,我们用个全局的int来存储,模拟一下硬件的状态。应用层通过系统调用 write / read 进行操作内核层通过注册对应的 struct file_operations 的对应的op callback, read跟write需要特别说明:1.

2020-06-15 16:35:12 300

原创 Linux Kernel Driver 设备驱动 之 字符设备

设备驱动的作用操作和管理硬件设备给用户提供访问操作硬件的接口linux内核设备驱动的分类字符设备驱动特性:设备的访问采用字节流形式包含的设备:串口(蓝牙,GPS,GPRS,zigbee等),按键,鼠标,触摸屏,LCD,声卡,各种传感器块设备驱动特性:设备的访问采用数据块形式,比如512byte,1K,4K包含的设备:硬盘,U盘,SD卡,TF卡,Nand,Nor,EMMC等网络设备驱动特性:设备的访问结合TCP/IP协议栈包含的设备:有线和无线...

2020-06-15 13:46:25 680

原创 Linux Kernel Driver 内核延时,并发,竞态

内核延时Linux 内核延时分为两种方式,一种 忙延时 一种 休眠延时。忙延时,CPU在原地空转,等待条件满足,适用于延时时间较短的场景。实现忙延时的API:ndelay(x) x 表示纳秒udelay(x) x 表示微秒mdelay(x) x 表示毫秒数如果延迟大于CPU能够响应的最短中断的时间,比如 ARM 架构 HZ 为100,那么响应中断的最短间隔为 10毫秒,如果延迟超过了该值(10毫秒),那么不再建议使用 忙延时,而采用休眠延时。忙延时,是不释放C...

2020-06-14 17:28:33 674

原创 Linux Kernel Driver 之 软件 timer

定时器1. 指定timeout时刻执行超时处理函数2. 一旦到期,内核会删除该定时器,超时处理函数只会执行一次3. 定时器基于软中断实现,在定时器的处理函数中,不允许休眠数据结构头文件 #include <linux/timer.h>expires: 不是超时时间,而是将来的某个时刻点 即 jiffies + timeout代码#include <linux/init.h>#include <linux/module.h>#inc

2020-06-13 23:05:52 259

原创 Linux Kernel Driver 之 硬件计时器

特点1. 能够周期性给CPU发送中断信号2. 周期或频率可以通过软件编程进行设置硬件定时器在Linux 内核中的更新中断处理函数具体干啥了呢?1. 最关键的是维护了一个全局变量的值 jiffies / jiffies_642. 更新墙上时间3. 检查进程是键盘是否用完,决定是否实施调度4. 检查是否有超时的软件定时器,如果有,将执行对应的软件超时中断处理函数5. 统计系统的资源信息等jiffies_64 & HZLinux 内核采用一个全局变量 j..

2020-06-13 20:03:06 639

原创 Linux Kernel Driver 中断 之 Tasklet & 工作队列

前言在 Linux 内核中,中断不属于任何进程,不参与进程的调度。如果中断的处理函数,长时间占用CPU,那么必将导致整个系统的并发和响应能力受到影响。所以:内核要求中断处理函数的执行速度要足够快,更不能进行休眠(注意是休眠,不是阻塞,操作系统底层的阻塞有可能是休眠实现,也有可能是CPU空转实现(类似 for (i = 0; i < 1024*1024*1024:i++);再比如spin_lock自旋锁,也会阻塞,但是可以用于中断上下文,因为自旋锁是CPU轮转实现的阻塞,而不是休眠阻塞)。但是,实

2020-06-13 13:24:27 265

原创 Linux Kernel Driver hello world 驱动续

介绍不干嘛,就注册一个中断号,看一眼,中断被触发一次,我们就打印一条日志。代码#include <linux/init.h>#include <linux/module.h>#include <linux/interrupt.h>MODULE_DESCRIPTION("Frocheng: Driver for DEMO!");MODULE_AUTHOR("Frodo Cheng");MODULE_LICENSE("GPL");MODULE_VE

2020-06-13 10:48:53 298

原创 Linux 内核系统调用与中断(学习笔记)

Linux 系统调用1. Linux 系统为每一个系统调用准备了一个号码,为系统调用号,对于32bit系统而言:exit 为 1, write 为4等。2. 每当应用程序调用系统调用函数时,如write,首先到 C 库中,(glibc中),调用对应的函数 write。3. C库中的writehansh ,将对应的调用号保存到对应的寄存器中,一般是R7寄存器。然后调用 SWI(old)或者SVC(new),触发一个异常(软中断),CPU需处理该异常(软中断),需跳转到异常向量表的对应位置去处理。

2020-06-12 18:38:49 642

原创 Linux kernel driver 入门01 写个驱动玩玩儿 加载/卸载 hello world

前言我们现在就写一个驱动小demo,环境准备:要有个linux系统,我的demo系统是一台老掉牙的笔记本上,装了个Ubunut18.04LTS 版本的系统。uname -a 命令我们查看一下这个系统的内核信息,如下:内核版本是 4.15.0. x86_64的系统。这个有什么用呢?就是下载对应的内核源码?我们要查询源码里面的一个文件。文件的目录是:linux-source-4.15.0/Documentation/kbuild在这个路径下有个 modulex.txt文件。很重要,我们要

2020-06-12 14:49:37 682

原创 FFMpeg 4.1 音频检测

前言网络上各种 FFMPEG,尤其是雷大神的一些样例,很好,但是一堆 deprecated 的API,编译看着是真心很烦。所以自己写了一个针对各种格式的输入音频,然后,也没复杂的功能,就是进行音频内部的一些检测。说一说音频格式关键的参数:1. 采样率2. 位深(说白了也就是精度)现实生活中的声音其实是连续的,而到电脑,手机等设备中的音频是数字的,离散的。连续的数据是如何变成离散的呢,就是录音,就是采样过程。这么说太抽象了,假设一个例子:我们现在来测一天的温度。怎么测?第一:多

2020-06-01 22:03:00 1944

原创 Linux 网络编程 gethostbyname, getaddrinfo,IPv4 与 IPv6 tcp server

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include &l...

2020-05-05 10:29:03 1789

原创 Linux 网络编程初探,TCP发送http请求到service 80端口小示例

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netdb.h>#include <arpa/inet.h>#include <sys/types.h>#include &lt...

2020-05-03 08:11:06 239

原创 Redis Source Code Read Log( 16 Redis 主从同步))

Replica 设置第一步replicationSetMaster1. 自身已经是 replica,该命令 change master,先断开与先前 master 的关系2. 当前自身所有的 blocked client 全部 free3. 当前节点如果有从节点,那么所有从节点全部断开4. 之前处理中的一些主从“hand shake”任务,暂且取消,执行新的主从“hand ...

2020-04-24 19:50:38 177

原创 Redis Source Code Read Log( 15 zset & pubsub & pipe))

Part 1 zsetRedis zset 是一个 sorted set 有序集合,其中的每一个元素都会关联一个 double 类型的 score,形成一个key-value pair。既然是集合,那个 key 是唯一的,但是score是可以重复的,但是score的类型必须是double,而key值的类型,必须是string。命令ZADD zset_name score member...

2020-04-22 18:24:58 159

原创 epoll 相关问题简单说明

阻塞、非阻塞、异步 I/O阻塞:以 read 为例,当 fd 中无数据,read 将进行等待,直到有数据为止,否则 read 将用于阻塞。“低速”系统调用。非阻塞:当 fd 中无数据可读,那么 read 不进行等待而直接返回,并且返回相应错误码(EAGAIN)。此时,怎么办呢?调用者可以以轮询的方式进行查看。如果不想轮询呢?系统提供了一套机制,帮助我们进行“轮询查看”工作,...

2020-04-17 19:54:14 1406

原创 分数转字符串形式的浮点数

分数转浮点数如:1 / 5 =0.21 / 3 = 0.(3)11 / 90 = 0.1(2)numerator: 分子denominator: 分母std::string fraction2string(int numerator, int denominator){ if (denominator == 0) { return ""; } if (...

2020-04-15 12:29:19 1039

原创 Redis Source Code Read Log( 14 AOF 详解(NOTE:此文较长))

Part 1: 相关配置介绍1. 总开关appendonly nono: 表示不开启 aof 功能yes: 表示开启 aof 功能2. 输出文件appendfilename “appendonly.aof”aof 输出的文件名3. 模式appendfsync everysec# appendfsync always# appendfsync n...

2020-04-11 05:18:42 294

原创 Redis Source Code Read Log( 13 rdb)

Part 1: rdb 三种方式1. save block main process2. bgsave [schedule] fork rdb child process3. background save by config fork rdb child process# save “”save 900 1 > 1 keys after 9...

2020-04-08 00:43:18 154

原创 Redis Source Code Read Log( 12 robj & sds)

Part 1: redisObject robjdefinitions针对原字节流,Redis内部根据不同场景,结合 sds 进行不同的 object 构造。而 object 模块就是“工厂模式”下,二进制字节流的消费者,以及 Redis server 中对象 redisObject(robj) 的生产者。type 域robj 内部元素的类型。这个类型的定义就是实际...

2020-04-06 20:37:56 163

原创 Redis Source Code Read Log( 11 list 之 block)

BLOCK 命令的业务逻辑:Redis 5.0.x 支持 三种类型的 block 操作1. list Blocked pop2. zset Blocked pop3. stream Blocked xread(5.0 新增)list 与 zset blocked pop 操作,逻辑基本一致。1. 客户端发送 block pop 命令2. 需要 pop 的 target ...

2020-04-06 14:14:21 134

原创 Redis Source Code Read Log( 10 data type: list 之 quicklist )

Part 01 quicklist 数据结构示意push 操作示意图quicklistEntryquicklistEntry: 内部记录一些指针以及状态,遍历quicklist时,记录同步更新记录遍历的准确位置。另,其中另有三个域,如下:longval:会直接记录解析的ziplist中存储的整型数。value 以及 sz 字段: 同时记录ziplist中存储...

2020-04-05 02:58:29 105

空空如也

空空如也

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

TA关注的人

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