- 博客(38)
- 收藏
- 关注
原创 嵌入式学习日记(38)HTTP
所谓”事务“就是指一组SQL命令,这些命令要么一起执行,要么都不被执行。就会隐式地开启了一个事务,如果插入一条数据,就调用该函数一次,事务就会被反复地开启、关闭,会增大IO量。如果在插入数据前显式开启事务,插入后再一起提交,则会大大提高IO效率,进而加数据快插入速度。插入19000+行的数据:24.087827 s。插入19000+行的数据:0.094387 s。2. http -->超文本传输协议。3. html -->超文本标记语言。1. url--->统一资源定位符。浏览器---->服务器。
2025-08-30 17:57:52
115
原创 嵌入式学习日记(37)数据库
select * from 表名 where 列 like "__梅";年-月-日 时:分:秒。create table 表名(列名1 数据类型,列名2 数据类型,列名3 数据类型);select * from 表名 where 列 like "%梅";3. 插入数据时,主键值自动增长列给NULL,让其自动增长。insert into 表名 values(值1, 值2, 值3);select 列名1,列名2,列名n form 表名;
2025-08-29 19:11:09
406
原创 嵌入式学习日记(36)TCP并发服务器构建——epoll
3. epoll通知内核开始进行事件监测 :int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);2. 添加关注的文件描述符:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);1. 使用红黑树(二叉树)实现文件描述符集合的存储,没有文件描述符上限限制,提高查找效率;events:保存返回的到达事件的结果(数组)
2025-08-28 17:36:36
1022
原创 嵌入式学习日记(35)TCP并发服务器构建
为了解决多线程或者多进程模型,在服务器运行过程,频繁创建和销毁线程(进程)带来的时间消耗问题。3. 使用select传递集合表给内核,内核开始监测事件 select()4. 当内核监测到事件时,应用层select将解除阻塞,并获得相关的事件结果。在不创建新的进程和线程的前提下,使用一个进程实现对多个文件读写的同时监测。exceptfds:其他事件的文件描述符集合。readfds:读事件的文件描述符集合。writefds:写事件的文件描述符集合。成功:返回内核监测的到达事件的个数。
2025-08-27 18:06:34
405
原创 嵌入式学习日记(34)HTTP协议
2. 应答机制:TCP对于每一包数据都会给出相应的应答。发送数据时序列号表示这包数据的起始编号,响应报文中的确认号是接收方收到的最后一个字节编号+1。3. 超时重传机制:当数据发送出去等待指定时间没有收到响应,此时认为这包数据丢失则进行冲传。Connection: keep-alive ---->长连接:连接保持一定时间。4. 滑动窗口机制:一段缓冲区,缓存TCP已发送未收到响应,准备发送等数据。3. 捎带应答机制:ACK报文可能和应用层的数据同时发送。ACK:响应报文标志位。
2025-08-26 17:27:57
233
原创 嵌入式学习日记(33)TCP
AA C0 00 00 00 F0 00 BB 10 A0 00 00 00 10 校验 BB AA C0 00 00 00 F0 00 BB 10 A0 00 00 00 10 校验 BB AA C0 00 00 00 F0 00 BB 10 A0 00 00 00 10 校验 BB。2. 接收方数据处理速度较慢,导致多包数据在接收缓冲区缓存,应用层读时,一次将多包数据读出。TCP粘包问题:发送方应用层发送的多包数据,将来在接收方可能一次读到,多包数据产生了粘连。
2025-08-23 18:34:06
973
原创 嵌入式学习日记(32)Linux下的网络编程
2)编辑--》虚拟网络编辑器--》更改设置--》VMnet0---》桥接至--》当前PC正在上网的网卡上--》应用--》确定。公有IP:由电信公司直接分配,并需要付费的IP地址, 可以直接访问internet。
2025-08-22 18:49:24
856
原创 嵌入式学习日记(31)信号、共享内存
管理员信号:只能按照默认方式处理,不能够被忽略和捕获 9) SIGKILL 19) SIGSTOP。使用内存映射技术,减少的数据的反复拷贝,提高了通信效率。编写程序,检测用户是否输入,如果用户3s内没有输入,则超时一次,如果超时3次则自动退出。功能:设置一个闹钟,当闹钟时间到达时,向自己所在的进程发送一个SIGALRM的信号。SIG_DFL:以缺省方式处理(系统默认方式)19)SIGSTOP: 让运行态的进程进入停止态(暂停)强制停止。函数的地址:以捕获方式处理(自定义)
2025-08-19 18:49:49
739
原创 嵌入式学习日记(30)线程通信、进程通信
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放(执行流本身使用着一把锁并不释放,还在请求别的锁)。(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺(A执行流拿着锁,其它执行流不能释放)。(1) 互斥条件:一个资源每次只能被一个进程使用(一个执行流获取锁后,其它执行流不能再获取该锁)。2. 读阻塞:读端和写端都存在,从管道中读数据,若管道为空,则发生读阻塞。1. 写阻塞:读端和写端都存在,向管道中写数据,当管道满时,发生写阻塞。写端:pipefd[1]
2025-08-18 19:52:54
583
原创 嵌入式学习日记(29)线程
5. 销毁锁:int pthread_mutex_destroy(pthread_mutex_t *mutex);4. 解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);3. 加锁:int pthread_mutex_lock(pthread_mutex_t *mutex);1. 分离属性:不需要被其他线程回收的线程称为分离属性得到线程,将来会被操作系统所回收。2. 非分离属性:可以被其他线程回收或者结束的线程,称为非分离属性的线程。
2025-08-16 19:16:45
277
原创 嵌入式学习日记(27)进程
2、让该进程成为孤儿进程,被系统回收。如何避免僵尸进程:1、子进程退出后父进程及时回收空间。孤儿进程:父进程在子进程之前消亡,子进程成为孤儿进程。命令用于显示当前进程状态。僵尸态Z:进程执行结束后空间未被回收。就绪态R:正在执行,未被CPU调度。结束态X:进程执行结束后空间被回收。运行态R:正在执行,被CPU调度。不可唤醒态D:使进程无法被调度。2.进程调度:由操作系统完成。1.执行结束 2、空间回收。1.进程创建 fork()可唤醒态S:阻塞等待进程。暂停态T:被暂停的进程。
2025-08-14 17:54:20
856
原创 嵌入式学习日记(26)UI技术
NULL:让操作系统自己分配用户空间。2. 获取显示设备相关参数(分辨率,像素格式)---》ioctl。失败:MAP_FAILED((void *)-1)Linux内核专门为图形化显示提供的一套应用程序接口。addr :映射的用户空间首地址。length:要映射的空间大小。1. 打开显示设备(/dev/fb0)3. 建立显存空间和用户空间的内存映射。4. 向映射的用户空间写入RGB颜色值。成功:映射的用户空间首地址。fd:显示设备文件描述符。prot: 操作权限。offset:偏移量。
2025-08-13 18:10:32
283
原创 嵌入式学习日记(25)文件IO
whence:要偏移的相对位置 SEEK_SET:文件开头位置 SEEK_CUR:文件当前读写位置 SEEK_END:文件末尾。O_CREAT: 创建文件。stdin ---->标准输入设备 ---->0。stderr ---->标准出错设备-----> 2。stdout ---->标准输出设备----->1。3. 无缓冲 0k -------->出错信息对应的设备。
2025-08-12 17:54:30
743
原创 嵌入式学习日记(24)标准IO、流定位接口
fgets :1、从指定文件读取最多一行 2、保留“\n”,加“\0” 3、最多读 size - 1 个字符,最后一位放“\0”gets :1、从终端读取 2、将末尾“\n”换成“\0” 3、读取时没有限制,可能造成越界访问。功能:向文件中写入nmemb个大小是size的数据到文件中。功能:从文件中读取nmemb个大小是size的数据。返回值:成功:返回实际写入的元素个数。返回值:成功:返回实际读取的元素个数。ptr:要写入的数据的首地址。nmemb:要写入的元素个数。nmemb:要读取的元素个数。
2025-08-11 17:59:59
252
原创 嵌入式学习日记(23)LINUX软件编程——文件操作
2、读写 fgetc/fputc fgets/fputs fread/fwrite。2、文件IO:Linux内核提供的操作方法——系统调用。1、标准IO:C语言库提供的操作方法——库函数。c :字符设备文件——输入输出设备、传感器。3、关闭 fclose。b :块设备文件——存储类文件。l :软链接文件——快捷方式。s :套接字文件——网络通信。p :管道文件——进程间通信。1.文件操作——一切皆文件。2、多任务——进程、线程。d :目录文件——文件夹。
2025-08-09 18:06:08
144
原创 嵌入式学习日记(22)树
树: n ( n≥0 )个结点的有限集合。n=0 ,空树。在任意一个非空树中,有且仅有一个特定的根结点当 n>1n>1 时,其余结点可分为 mm 个互不相交的有限集合 T1,T2,T3,…,TmT1,T2,T3,…,Tm ,其中每一个集合又是一个树,并且称谓子树。
2025-08-08 18:45:29
277
原创 嵌入式学习日记(21)顺序表、哈希表
哈希存储:将要存储的数据的关键字和存储位置之间建立起对应关系,这个关系称为哈希函数。存储时通过对应的哈希函数将数据映射到指定位置,查找时仍通过该函数找到数据。哈希冲突(哈希矛盾):key1!= key2,f(key1) = f(key2)利用链地址法创建哈希表制作电话簿。存储位置 = f(key)
2025-08-07 17:55:26
135
原创 嵌入式学习日记(20)栈
队列:允许从一段进行数据插入,另一端进行数据删除的线性存储结构,插入称为入队,删除称为出队,入队端称为队尾,出队端称为队头,遵循先进先出原则(FIFO)offset_of :获取内核链表中的链表节点到结构体起始位置的偏移量。顺序栈:数据存储在顺序表(数组),分为满增栈、满减栈、空增栈、空减栈。栈:1、局部变量 2、函数的形参、返回值 3、函数的调用关系。栈结构:只允许从一段进行数据的插入及删除的线性存储结构。内核链表不将数据存储在节点中,而是将节点嵌入到数据中。满、空:根据栈顶是否存在数据判断。
2025-08-06 19:05:50
148
原创 嵌入式学习日记(19)双向链表
Makefile 由一系列规则(rules)组成,每条规则定义如何生成目标文件及其依赖关系。◦ prerequisites:依赖的文件或目标(空格分隔)◦ target:生成的文件名或操作名称(如 clean)◦ recipe:执行的命令(必须以 Tab 开头)4、链接,处理多文件及函数的链接关系。1、预处理,处理和 # 相关的指令。3、汇编,将汇编指令生成二进制指令。◦ $^:所有依赖文件(去重):比目标更新的依赖文件。◦ $<:第一个依赖文件。◦ $*:% 匹配的部分。◦ $@:当前目标名称。
2025-08-05 19:09:42
126
原创 嵌入式学习笔记(18)单向链表
2、编辑→虚拟网络编辑器→更改设置→VMnet0→桥接→桥接到PC正在上网的网卡→应用→确定。valgrind :内存探测工具,用来监测内存错误和内存泄露。1、虚拟机→设置→网络适配器→桥接模式→确定。利用快慢指针法找到链表的倒数第K个元素。利用快慢指针法找出链表的中间值。
2025-08-04 20:13:19
147
原创 嵌入式学习日记(17)——数据结构
数据结构内容:1、链表(单向、双向、循环、内核)2、栈 3、队列 4、二叉树 5、哈希表 6、常用算法。(4)散列结构(哈希结构):将数据的存储位置与元素间的关键字建立起对应关系。(2)、线性关系:元素之间存在一对一的关系(顺序表、链表、队列、栈)(4)、图形结构:元素之间存在多对多的关系(网状结构)(3)、树形结构:元素之间存在一对多的关系(二叉树)链表:存储数据的对象->属性(变量)、行为(函数)2、对链表进行操作:插入、删除、查找、修改、销毁。(1)、集合:元素之间平等的集合关系。
2025-08-02 19:26:37
143
原创 嵌入式学习日记(16)
按位与:将两数二进制展开,按位进行与运算;功能:指定位清零,要求操作数与整型相兼容。<< 左移:将一个数二进制展开,左移几位就删去前几位,并在后面补上对应个数的0。将不同类型的数据组合为一个整体,谷歌编程规范要求首字母大写,大括号后有分号。结构体的初始化顺序与声明顺序一致,若进行部分初始化,剩下的部分默认为0。| 按位或:将两数二进制展开,按位进行或运算;2、在结构体成员中找到最长的成员,最终按该成员的长度对齐。1、默认按CPU位数对齐,最终大小为8的整数倍。结构体的声明允许嵌套。
2025-07-31 19:52:31
196
原创 嵌入式学习日记(15)
动态内存分配 memory allocate。使用动态内存分配需要包含一个标准库头文件。函数指针:指向函数的指针,降低程序耦合性。指针数组作为函数参数,形参是二级指针。二级指针:指向指针的指针。
2025-07-30 19:34:23
149
原创 嵌入式学习日记(14)
int (*p)[10] 数组指针 int *p[10] 指针数组。sizeof(&a[0]) = 8 , sizeof(&a[0])相当于 sizeof(int*)sizeof(a) = 40 , sizeof(a) 相当于 sizeof(int[10])指针函数是指返回值为指针类型的函数,不能返回局部变量地址。a[i][j] 等价于 *(*(a + i) + j)二维数组作为函数参数传递,形参是指向一维数组的指针。void *p 万能指针,不能做指针运算。
2025-07-29 17:55:05
145
原创 嵌入式学习日记(13)
迭代器:提供一种方法顺序访问聚合对象中的元素,而无需暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出来,使得聚合对象可以专注于数据存储,而迭代器负责遍历。对指针类型进行加法运算,p + n 的结果依旧是指针,新指针是在原来的地址上加 n * (sizeof(基类型))个字节。指针与指针之间不能求和,可以求差,结果表示相差几个基类型(要求两个指针基类型相同)利用字符串指针编写遍历函数及有效字符长度函数。快速排序 算法复杂度 nlgn。指针函数:返回值为指针的函数。利用指针函数实现二分法查找。
2025-07-28 19:43:15
129
原创 嵌入式学习日记(12)
i = 1000 直接访问 *p = 1000 间接访问。双引号与尖括号的区别在于文件名使用的是相对路径还是绝对路径。2、从定位处开始向后偏移 sizeof (基类型)的字节。64位操作系统下地址占8字节,32位占4字节。3、将偏移后的那部分内存当作一个基类型变量。1、根据指针变量所保存地址去内存中定位。此处的 * 是类型说明,不是指针运算。指针的作用:在被调函数中修改主调。gcc -E 表示只做预处理。
2025-07-26 17:32:44
182
原创 嵌入式学习日记(11)
4、在两个或多个有包含关系的作用域中定义的同名标识符,外层在内层不可见(就近原则)static 的作用:1、定义静态局部变量2、限制函数的使用范围为本身。register int k :定义寄存器变量,提高读写速率,不可寻址。变量的生存期分为静态与动态,静态生存期与程序的运行周期相同。2、在没有包含关系的两个不同作用域中的同名标识符互不影响。静态区(全局区):全局变量、静态局部变量。栈区:局部变量、函数形参、返回地址。全局变量的生存期为静态生存期。
2025-07-25 17:15:10
143
原创 嵌入式学习日记(10)
栈的数据结构:FILO first in last out ,先进后出。函数传参是值传递,无法在被调函数中改变原函数中的变量。栈区、堆区、字符串常量区、代码区、静态区。指针传参能在被调函数中修改主调。将函数调用到本地:地址传导。函数参数默认自右向左传参。求斐波那契数列的第n位。利用函数实现二分查找法。
2025-07-24 18:19:25
141
原创 嵌入式学习日记(9)
求二维数组的列数:sizeof(a[0]) / sizeof(a[0][0])可以将二维数组 a[i][j] 看作是由 m 个长度为 n 的数组组成。求二维数组的行数:sizeof(a) / sizeof(a[0])函数:判断输入年份是否为闰年及输出给定区间的闰年。可以省略元素个数,但是只能省略行数。若无 return ,返回值不确定。函数:输入年月,得到该月的天数。将二维数组以列为单位逆序排列。函数的作用:提高代码的复用性。若未定义,返回值默认为整型。函数的返回值不能为数组。
2025-07-23 19:02:45
221
原创 嵌入式学习日记(8)
fgets(s,sizeof(s),stdin) :从终端获取数组中的元素。创建一个中间数将数组分为两部分,判断要查找的数在哪个部分,循环这一操作。当数组中的元素不为结束标志时计数,得到的结果就是数组中的有效字符个数。<string.h> :用于调用操作字符数组的函数的头文件。将 s1 数组中的元素一个一个复制到 s2 数组中去。字符数组的作用:使字符串常量能在程序中动态变化。比较字符串大小: strcmp(s1,s2)将数组 s2 的内容连接到数组 s1 后面。\0 :空字符,是字符数组的结束标志。
2025-07-22 19:02:13
186
原创 嵌入式学习日记(7)
数组的长度 length = sizeof(a) / sizeof(a[0]) :数组的元素个数可以通过数组在存储空间占的总字符数除以一个元素的长度得到。一维数组的初始化:在定义数组时使用初始化列表器,为初始化的元素默认为0。选择排序:将数组中的元素从前到后两两比较,比较后将较大的数字往后置位放。数组的下标超出数组元素的个数会导致越界访问,可能覆盖存储中的其他数据。冒泡排序:将相邻的元素进行比较,较大的元素放在右边。创建数组和引用数组元素时的中括号具有不同的功能。数组的数组名代表的是数组的首元素的地址。
2025-07-21 22:58:45
304
原创 嵌入式学习日记(6)
do while 与 while 的区别:do while 先执行再判断表达式真假,至少会执行一次;循环控制的三要素:1、循环变量初始化语句 2、循环的执行条件 3、使循环趋于结束的语句。break 语句会打断 for 语句中的表达式3的计算,只打断break所处的该层循环。三目运算符,若表达式1为真,则结果为表达式2;若表达式1 为假,结果为表达式3。continue 循环短路语句:打断该次循环,进行下一次循环。循环结束时,循环变量的值为首次时循环结束的值。= 0)等价于 if(a)
2025-07-19 18:01:39
101
原创 嵌入式学习日记(5)
判断一个年份是否为闰年:year % 4 == 0 && year % 100!表达式阶段:&&左操作符若为0,右操作数截断不计算;||左操作数若为1,右操作数截断不计算。连续关系表达式从左往右计算,计算后将结果0或1带入继续计算,因此要避免使用连续比较。i 和 i == 0都可以用来判断 i 是否为0。在语句中将不同功能的程序分开运行,降低程序耦合性。关系表达式结果是整型,1表示真,0表示假。return 终止程序运行。&&逻辑与:有0即为0。
2025-07-18 19:46:25
136
原创 嵌入式学习日记(4)
缓冲区:由于处理数据的能力不同,输入的数据被按顺序存放在队列中,按下回车键时CPU将队列中的数据一个一个进行处理。若m过小则以实际宽度为准。%#05X:以大写字母形式输出十六进制数,输出结果宽度为5个字符,不足时在左边补0,带有0x前缀。%hd:输入short 型 %nd:取前n位输入。%o:无符号八进制 %x:无符号十六进制。%g:在%e和%f中选择较短的 const char *:字符串常量。
2025-07-17 18:52:43
176
原创 嵌入式学习日记(3)
求余:只能对整型或与整型兼容的数据类型进行求余操作,结果的正负和左操作数有关且结果小于右侧。lvalue(left value):左值,一般为变量,l也可以理解为locatable。rvalue(right value):右值,一般为常量,r也可以理解为readable。短数值类型赋值给长数值类型,在前面补空位,根据符号位决定补0或1;不同数据类型的混合运算:从右往左的箭头表示必转,从下往上的箭头表示隐式转换。变量初始化:在创建变量的同时给变量一个初始值。临时变量(匿名变量):右值。显式转换(强制转换)
2025-07-16 19:21:48
321
原创 嵌入式学习日记(2)
浮点型变量存储:先根据数的正负确定符号位,然后将数字转化为二进制形式(小数点后的数使用辗转相乘法得到:不断乘二直到小数部分为0,将乘积的整数部分从前往后记),再将得到的二进制数用科学计数法表示,科学计数法表示后的小数部分即为尾数,2的次方数加127后转化为二进制数得到阶码,按符号位、阶码、尾数的顺序排列后再用0补齐32位,最后转化为十六进制,按照小端存储原则存储到RAM中。short (2字节)存储范围:[-2^15,2^15-1] unsigned short 存储范围:[0,2^16-1]
2025-07-15 23:51:04
434
原创 嵌入式学习日记——C语言
vi main.c 创建文件并打开编译器界面,默认为命令模式,按 “i” 进入编辑模式编写程序,按 “Esc” 退出编辑模式返回命令模式,在命令模式下 输入“:w” 进行保存,输入 “:q” 退出编译器,输入 “:wq” 保存并退出,输入 “:q!退出后使用 gcc指令编译程序,若程序无错误则生成可执行文件,文件名默认为 a.out,输入./a.out显示运行结果。touch 创建文件;mkdir 创建文件夹;相对路径:相对于当前目录的路径 ./ 表示在当前目录下,../表示在上一级目录下。
2025-07-14 23:03:48
221
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人