笔记 嵌入式Linux C

01 嵌入式Linux C_进程与线程

原创转载链接:https://blog.csdn.net/weixin_45781914/article/details/108916984

1.定义

进程是资源分配的单元,线程是资源调度的单元。两者就像生活中房子(进程)和房间(线程)的关系。
线程只能属于一个进程,但一个进程可以有多个线程。

2.异同之处

1). 通信方式上:

	进程间通信,通过管道,共享内存,消息队列,socket,信号量共5种方式。
	线程间通信,通过全局变量,锁,文件方式。

2). 执行效率上:

	进程在切换时,需要重新把线程移至缓存,耗时大。相较于线程直接从缓存中找要慢很多。二者本制区别是地址切换。
	特例补充说明:
	前后两个执行的任务都在同一个进程中,则不存在太多的地址切换。不过发生的概率比较低。
	Q1:既然线程比进程执行速度块,创建代码的时候,只用线程好了,不用进程可以吗?
	A1:不可以。从健壮性和安全性考虑的话,不能只创建线程,而不创建进程。

3.适用场景:

	Q2:什么时候用线程,进程?
	A2:从以下三个方面考虑:
		判断这个任务和当前进程任务的紧密程度;
		该任务崩溃后,影响大不大;
		执行效率考虑。
		# 01嵌入式Linux C_进程与线程

02 嵌入式Linux C_栈和堆

在这里插入图片描述

1.内存空间

	栈的内存 ,Linux是8KB,由编译器自动分类与释放;
	堆的内存,最多申请3GB(进程空间最大为3GB),实际取决于进程实际空间,由程序员手动分配(malloc函数)与释放(free函数)。

2.位置

	栈是自顶向下增长,堆则是自下而上使用。
	备注:
		栈的大小可以更改,Linux提供ulimit -s指令来对栈的大小进行修改。

3.问答

	Q1:如果系统处于用户态,用malloc函数申请堆的内存,系统崩溃,没有被释放的内存,会不会被释放掉?
	A1:会。进程回调,会有的引用和内存会被释放掉。

03 嵌入式Linux C_中断

问答

	Q1:为什么有中断?
	A1:响应,处理外部设备的特殊事件。
	Q2:中断和轮询?区别?选择?
	A2:中断时被动的响应外部请求,非实时,不可控;
		轮询是主动询问请求,实时,可控。
		二者共用(NAPI技术实现),二者适用于不同的场景,在于设备本身的特性。
	Q3:中断类型,与异常的区别?
	A3:外部中断,内部中断。中断和异常都是处理的一种方式,异常极有可能引发中断,用中断的方式处理当前的异常。
	Q4:如何处理中断?中断的应用场景,如何被使用?使用时注意哪些?什么是中断上下文,进程上下文?怎么设计中断?
	A4:中断上下文:可以理解为硬件传递过来的这些参数和内核需要保存的一些环境,主要是被中断的进程的环境。
		进程上下文:当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。
		响应中断时,先现场保持(存储任务,环境),然后布置中断入口。
		中断上文响应紧急事务(不可以睡眠,也不可以处理其他调用),返回后,中断上文结束;
		中断下文处理不是很紧急的任务(但有实时性要求)。
	注意:中断可以及时响应,不代表会及时执行。整个事情完成后才叫中断。

04 嵌入式Linux C_用户态和内核态

问答

	Q1:用户态和内核态区别?
	A1:资源操作权限不同。
			用户态无法调用内核态相关资源,内核态也不会干涉用户态的资源使用,二者相互协作。
		运行空间不同。
			Linux中0-3GB作为用户态使用,3-4GB作为内核态使用(内核只有一个)。所有的用户态进程共享一个内核,二者不可以互相访问(执行权限不同)。
	Q2:内核态能否访问用户空间的一些数据?
	A2:可采用短暂更改内核空间的方式。由3-4GB改为0-3GB,访问完后再改回来。
	Q3:用户态如何访问内核态,有几种方式?***重点***
	A3:系统调用(不同于C函数调用,区分开);中断(中断返回的时候处于内核态);异常。
备注:从用户态到内核态,需要进行权限切换,地址空间切换。
	Q4:为什么把系统调用叫做用户态切换到内核态,或内核态帮助用户态执行相应的执行任务,或用户态嵌入到内核态?
	A4:每一个任务都有一个结构体记录当前的任务,当做了一个系统调用(通过异常,中断等方式),pid(指向当前CPU正在执行的任务是谁)改变,内核不认识pid,实际任务指向的进程,还是用户态指向的进程且是在内核态执行的。
	Q5:用户态和内核态如何通信?
	A5:IO-Controler;发消息;socket;文件。

05 嵌入式Linux C_锁

定义

	只有有限个人可以占有,锁住的是关键结构,数据,区域。

分类

	种类:自旋锁(原子锁),信号量,互斥锁,读写锁。
		自旋锁:多个CPU同时进入一个关键的数据结构,锁CPU。禁止了中断,调度,常应用于中断中。
		信号量:可以睡眠,可以被调度,不可以用于中断。
	备注:自旋锁不可以嵌套互斥量。
	扩充:内存屏障,挡住编辑器进行优化,按照设定的顺序执行。当物理存储信息和内存存储的信息是不对称时,有可能是还没有回写造成的。

06 嵌入式Linux C_字节对齐

问答

	Q1:为什么结构体本身需要字节对齐?
	A1:平台原因(移植原因):
		不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取特定类型的数据,否则会抛出异常。
		性能原因:
		数据结构(尤其是栈)应该尽可能在自然边界上对齐,原因在于,为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问仅需要一次访问。

举例

	例题1:结构体,三部分组成,char,int,char,sizeof(结构体) = 12B
	解析:字节对齐中,既要数据本身字节对齐,结构体本身也要对齐。
	例题2:
		#pragma pack(2)
		struct AA {
		int a;       //长度4 > 2 按2对齐;偏移量为0;存放位置区间[0,3]
		char b;  //长度1 < 2 按1对齐;偏移量为4;存放位置区间[4]
		short c;     //长度2 = 2 按2对齐;偏移量要提升到2的倍数6;存放位置区间[6,7]
		char d;  //长度1 < 2 按1对齐;偏移量为7;存放位置区间[8];共九个字节
		};
		#pragma pack()
	扩充:对于同步和异步,单任务时,不需要考虑同步和异步。多任务或进程执行时,才会考虑此问题。
		强关联,严格时间关系用同步;弱关联用异步。

07 嵌入式Linux C_实时系统和非实时系统

问答

	Q1:区别?判断标准?
	A1:实时系统,VxWorks,freeRTOS;非实时系统,Windows,Linux,Android。
		嵌入式实时系统:能够准确预估当前任务被执行的时间;如生活中的地铁,汽车则不是。
	Q2:实时系统和非实时系统的本制区别?
	A2:任务调度方式不同。
		大部分实时系统是可抢占式的,高优先级任务优先得到执行(实时操作系统的中断,尽量采用轮询的方式,可控性);非实时操作系统,调度复杂。
		使用场景不同。
	扩充:看门狗分为软件看门狗和硬件看门狗,通过重启来实现。

08 嵌入式Linux C_TCP UDP

区别

	TCP UDP同属于TCP/IP协议(依次是物理层,数据链路层,网路层,传输层和应用层,实际使用)的传输层。
	TCP:可靠,构建了可靠的传输通道,双方确认信息;开销大,网络时延不稳定;以数据流的方式传输,建立TCP服务器端口时,需要Accept。
	UDP:不可靠;开销小,实时性很好;以报文的方式传输,建立UDP服务器端口时,不需要Accept,只需要IP地址和端口。

TCP的三次握手

	第一次:客户端向服务器发送SYN j 包;
	第二次:服务器向客户端发送ACK+SYN;
	第三次:客户端向服务器发送ACK包。

TCP的四次挥手

	第一次:客户端向服务器发送FIN报文,请求断开;
	第二次:服务器向客户端发送ACK,表示已经收到客户端的请求,还需要等待一下;(收拾一下建立连接的东西,即现场开销,需要一定时间来回收)
	第三次:服务器向客户端发送FIN,确认客户端可以断开连接;
	第四次:客户端向服务器发送ACK应答。

09 嵌入式Linux C_MTU和MSS

概述

	Q1:MTU与MSS区别与联系?
	A1:以太网传输时,每次报文传输的大小 <= 1512字节。
		MTU(最大传输单元):以太报文中,上限是1512字节。MTU值可以改变。
		MSS(最大分节大小):MSS值是MTU值减去TCP,IP头部的报文值(IP,TCP头各至少20B)。即一次可以接收报文的大小。
本书所附光盘使用说明 本光盘中包括了书中所有示例的源代码和书中所有的插图,具体说明如下。 程序代码文件夹中包含了本书的所有源代码。 程序代码\chapter02 文件夹中包含了第2章的示例源程序。其中hello.c和hello.h是2.3.2的源代码,gdb.c是2.4.1的源代码,test.c是动手练练的源代码。 程序代码\chapter06 文件夹中包含了第6章的示例源程序。其中pointer1.c是6.2.2的第一个源代码,pointer2.c是6.2.2的第二个源代码,pointer3.c是6.2.2的第三个源代码,pointer4.c是6.2.3的第一个源代码,pointer5.c是6.2.3的第二个源代码,pointer6.c是6.2.3的第三个源代码,pointer7.c是6.2.3的第四个源代码。 程序代码\chapter08 文件夹中包含了第8章的示例源程序。其中binary_tree.c是二叉树的源代码,list.c是线性链表的源代码。 程序代码\chapter09 文件夹中包含了第9章的示例源程序。其中lock.c是文件锁的源代码,seri.c和seri.h是串口设置的源代码,read_seri.c是读串口的源代码,write_seri.c是写串口的源代码。 程序代码\chapter10 文件夹中包含了第10章的示例源程序。其中alarm_read.c是设置信号函数的源代码,dameon.c是守护进程的源代码,zombie.c是僵尸进程的源代码。 程序代码\chapter11 文件夹中包含了第11章的示例源程序。其中socklib.c是网络相关通用函数的源代码,tracert.c是traceroute的源代码,webserv.c是web服务器的源代码。 程序代码\chapter12 文件夹中包含了第12章的示例源程序。其中skull.c是skull驱动程序的源代码,s3c2410fb.c和s3c2410fb.h是LCD驱动的源代码。 程序代码\chapter13 文件夹中包含了第13章的示例源程序。其中args_cmd.h是解析命令相关的头文件,ctrl.c和ctrl.h是控制命令的源代码,proc_cmd.c是具体操作的源代码,thread.c和thread.h是线程相关的源代码,types.h是类型相关的源代码,net_send.h是网络相关的源代码。 书中插图包含了本书所有的插图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值