《Linux知识点》

(21条消息) 嵌入式面试知识点总结 -- C语言篇_不积跬步,无以至千里-CSDN博客

(21条消息) 日常生活 -- 嵌入式面试_不积跬步,无以至千里-CSDN博客

 https://blog.csdn.net/weixin_42145502/article/details/107743404?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-107743404-blog-121218400.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-107743404-blog-121218400.pc_relevant_aa&utm_relevant_index=7

 

什么时候用多进程,什么时候用多线程?

多进程:安全性高
多线程:频繁创建或者销毁,以及切换上下文。
 
 
 

进程:

1、什么是进程
  进程是操作系统运行程序的一个实例,也是操作系统分配资源的单位。在 Linux 环境中,每个进程都有独立的进程空间,以便对不同的进程进行隔离,使之不会互相影响。

3、进程的特征
动态性: 进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
并发性: 任何进程都可以同其他进程一起并发执行。
独立性: 进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
异步性: 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的,不可预知的速度向前推进。
结构特征: 进程有程序、数据、和进程控制块三部分组成。
多个不同的进程可以包含相同的程序: 一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。
4、进程终止
有 8 种方式使进程终止,其中 5 种为正常终止,它们是:
(1)从 main 返回
(2)调用 exit
(3)调用 _exit 或 _Exit
(4)最后一个线程从其启动例程返回
(5)从最后一个线程调用 pthread_exit
异常终止有 3 种方式,它们是:
(6)调用 abort
(7)接到一个信号
(8)最后一个线程对取消请求做出响应。

进程线程的状态转换图 什么时候阻塞,什么时候就绪?

 

 

父进程、子进程的关系以及区别?

父子进程的概念:调用fork、vfork、clone的进程就是父进程,生成的新的进程就是为子进程。

父子相同处: 全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...
父子不同处: 1.进程ID   2.fork返回值   3.父进程ID    4.进程运行时间    5.闹钟(定时器)   6.未决信号集

子进程复制了父进程0-3G用户空间内容,以及父进程的PCB,但pid不同。

但是用到了写时拷贝技术。

 

fork、vfork、clone的区别?

fork:当调用完fork函数后,子进程获得父进程的数据空间、堆和栈,但是这是子进程单独拥有的,并不和父进程共享,因此修改子进程的变量不会影响父进程的变量。父进程和子进程共享正文段。

  由于在fork之后经常跟随着exec,所以现在的很多实现并不执行一个父进程数据段、栈和堆得完全副本,作为代替,使用了写时复制(copy-on-write,COW)技术。

  写时复制:写时拷贝是一种可以推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间。只用在需要写入的时候才会复制地址空间,从而使各个进行拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候。在页根本不会被写入的情况下---例如,fork()后立即执行exec(),地址空间就无需被复制了。

 

vfork:

  vfork的使用和fork是一样的。

执行次序:

  vfork是先调用子进程,等子进程的_exit(exit是不正确的)或exec被调用后,再调用父进程(在此之前,父进程一直被挂起)。

  fork对父子进程的调度室由调度器决定的。

数据段的影响:

  fork采用的是写时复制技术。

  vfork的父子进程是共享数据的,所以在子程序中修改变量,父进程的变量也会被修改。(在fork中不会这样)

  总结:vfork创建的子进程调用exec前,与父进程是共享一个地址空间的(根本不存在复制的这个步骤,因此直接执行exec效率方面比fork快)。但是需要注意的是:如果子进程修改数据、进行函数调用或者没有调用exec或exit就直接return(return后,会释放局部变量并弹栈。但是因为vfork是共享父进程的地址空间,那么换句话说也就是return掉了main函数。return后还会调用类似exit这样的退出函数。那么就又回到父进程的vfokr往下运行,但是由于之前子进程return掉了main函数的栈,所以会出现段错误。这就类似C++中return会调用局部对象的析构函数,exit不会,是直接退出)会总成未知的后果。

 

clone:

  fork是全部复制,vfork是共享内存,而clone则可以讲父进程资源有选择复制给子进程,而没有复制的资源则通过指针的复制让子进程共享。

 

什么是进程上下文、中断上下文?

   进程上下文:一个进程在执行时,CPU的所有寄存器中的值、pc、进程的状态以及堆栈中的内容被称为该进程的上下文。

  中断上下文:可以理解为硬件传递过来的参数和内核需要保存的一些环境,主要是被中断的进程的环境。

  被中断的进程环境:当前进程的用户态会进程CPU上下文切换,进入用户态。也就是被中断的进程环境指的是CPU寄存器的值以及PC。

 

一个进程可以创建多少线程,和什么有关?

   进程的虚拟内存空间上限,因为创建一个线程,操作系统需要为其分配一个栈空间,如果线程数量越多,所需的栈空间就要越大,那么虚拟内存就会占用的越多。

  系统参数限制,虽然 Linux 并没有内核参数来控制单个进程创建的最大线程个数,但是有系统级别的参数来控制整个系统的最大线程个数。

   可以执行 ulimit -a 这条命令,查看进程创建线程时默认分配的栈空间大小,比如我这台服务器默认分配给线程的栈空间大小为 8M。

  

   在 32 位 Linux 系统里,一个进程的虚拟空间是 4G,内核分走了1G,留给用户用的只有 3G。

  那么假设创建一个线程需要占用 10M 虚拟内存,总共有 3G 虚拟内存可以使用。于是我们可以算出,最多可以创建差不多 300 个(3G/10M)左右的线程。

  (37条消息) 一个进程最多可以创建多少个线程?_小林coding的博客-CSDN博客_一个进程可以有多少个线程

 

并发,同步,异步,互斥,阻塞,非阻塞的理解?

  并发:在操作系统中,同个处理机上有多个程序同时运行即并发。

  互斥:同一个资源同一时间只有一个访问者可以进行访问,其他访问者需要等前一个访问者访问结束才可以开始访问该资源,但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

  同步:同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。

  异步:异步和同步是相对的,异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。

  阻塞:主程序会等到函数读取完再继续往下执行。

  非阻塞:读取函数会立刻返回一个状态值给主程序,主程序不等待文件读取完就继续往下执行。
  
同步阻塞:发送方发出请求后一直等待(同步),接收方开始读取文件,如果不能马上得到读取结果就一直等,直到获取读取结果再响应发送发,等待期间不可做其他操作(阻塞)。

  异步非阻塞:发送方发出请求后,不等待响应,继续其他工作(异步),接收方读取文件如果不能马上得到结果,也不等待,而是马上返回取做其他事情。当IO操作(读取文件)完成以后,将完成状态和结果通知接收方,接收方在响应发送方。

 

线程同步与阻塞的关系?同步一定阻塞吗?阻塞一定同步吗?

  阻塞和同步在表现上确实很像,阻塞看起来确实是卡着不动,同步也是的。但阻塞其实不叫卡,因为它是调用了某个系统调用,而这个系统调用让它的调用线程睡眠了,此时是不占cpu的。但是,实现同步的方式除了阻塞之外,非阻塞也能实现。比如你弄一个while循环一直等一个标志位置位。

  非阻塞跟异步的概念也是完全不同的,完全可以使用非阻塞的系统调用,然后轮巡等待就绪。

  阻塞的时候,cpu会重新调度线程,就会是异步阻塞了。

   (37条消息) 线程-----同步异步,阻塞非阻塞_林浩吧的博客-CSDN博客

阻塞等于同步,非阻塞等于异步这种说法有什么错误? - 知乎 (zhihu.com)

 孤儿进程、僵尸进程、守护进程的概念

 

如何创建守护进程?

 

正确处理僵尸进程的方法?

进程间通信

问题一:进程间通信有几种方式?
进程间通信 (IPC)方式有:
(1)管道
(2)消息队列
(3)信号量
(4)共享存储
(5)套接字(socket)
其中消息队列、信号量、共享存储统称为 XSI IPC通信方式。

 

(1)管道

管道分为无名管道和有名管道。

无名管道

无名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用,进程的亲缘关系一般指的是父子关系。无名管道一般用于两个不同进程之间的通信。

当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,,这样提供了两个进程之间数据流动的一种方式。

有名管道也是一种半双工的通信方式,但是它允许无亲缘关系进程间的通信。

它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。

无名管道

优点:简单方便;

缺点:

局限于单向通信

只能创建在它的进程以及其有亲缘关系的进程之间;

缓冲区有限

有名管道

优点:可以实现任意关系的进程间的通信;

缺点:

长期存于系统中,使用不当容易出错;
缓冲区有限
(2)信号量
信号量是一个计数器,可以用来控制多个线程对共享资源的访问。它不是用于交换大批数据, 而用于多线程之间的同步,它常作为一种锁机制,防止某进程在访问资源时其它进程也访问该资源,因此 , 主要作为进程间以及同一个进程内不同线程之间的同步手段。

优点:可以同步进程。

缺点:信号量有限。

(3)消息队列

消息队列是消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点。

消息队列是UNIX下不同进程之间可实现共享资源的一种机制,UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程,对消息队列具有操作权限的进程都可以使用msget完成对消息队列的控制,通过使用消息类型,进程可以按任何顺序读信息,或为消息安排优先级顺序。

优点:可以实现任意进程间的通信,并通过系统调用函数来实现消息发送和接收之间的同步,无需考虑同步问题,方便。

缺点:信息的复制需要额外消耗CPU的时间,不适宜于信息量大或操作频繁的场合。

(4)共享内存

共享内存是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问,共享内存是最快的IPC(进程间通信)方式, 它是针对其它进程间通信方式运行效率低而专门设计的,它往往与其他通信机制,如信号量,配合使用,进而实现进程间的同步与通信。

共享内存的特点:

共享内存是以传输数据为目的 。
共享内存无同步无互斥 。
共享内存是所有进程间通信速度最快的。
共享内存的生命周期随内核
优点:使用共享内存进行进程间的通信非常方便,而且函数的接口也简单,数据的共享使进程间的数据不用传送,而是直接访问内存,加快了程序的效率。同时,它也不像无名管道那样要求通信的进程有一定的父子关系。

缺点:

通信是通过将共无法实现享空间缓冲区直接附加到进程的虚拟地址空间中实现。
利用内存缓冲区直接交换信息,内存的实体存在于计算机中,只能让同一个计算机系统中的诸多进程共享,不方便多个计算机网络通信。
共享内存没有提供同步的机制,这使得我们在使用共享内存进行进程间通信时,往往要借助其他的手段来进行进程间的同步工作。

socket:主要⽤于⽹络中的进程间通信,通信过程以及数据复杂,但安全可靠。

UNIX再学习 -- 进程间通信之管道_聚优致成的博客-CSDN博客

UNIX再学习 -- XSI IPC通信方式_聚优致成的博客-CSDN博客

UNIX再学习 -- 网络IPC:套接字_聚优致成的博客-CSDN博客

 

线程
问题:
问题一:什么是线程,进程与线程的的关系?
解答:
线程和进程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个主线程。它们共享进程的地址空间;而进程有自己独立的地址空间。
(2)同一进程内的所有线程共享该进程的所有资源。
(3)线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(4)进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
(5)在创建或撤销进程时,由于系统要为之分配和回收资源,导致系统的开销大于创建或撤销线程时的开销。
(6)不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行。

线程同步

问题:
问题一:线程同步有几种方法?
线程同步方式:互斥量、读写锁、条件变量、信号量、自旋锁。

 

信号量与互斥量的区别?

(1)、互斥量用于线程的互斥,信号量用于线程的同步。互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
(2)、互斥量值只能为0/1,信号量值可以为非负整数。也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

(3)、互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。


问题二:什么是死锁?
  死锁:当多个线程用多个锁去竞争同一种资源而造成的进入互相等待的状态,或者同一个锁,对同一种资源进行反复加锁。

  常见的死锁有如下两种:

  递归死锁:中断等延迟操作中使用了锁,和外面的锁构成了递归死锁。

  AB-BA死锁:多个锁因处理不当而引发死锁,多个内核路径上的所处理顺序不一致也会导致死锁。


问题三:死锁的四种产生条件是什么?
虽然进程在运行过程中,可能发生死锁,但死锁的发生必须具备一定的条件,死锁的发生必须具有以下四个必要条件。
(1)互斥条件
指进程对所分配的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用完释放。
(2)请求和保持条件
只进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
(3)不剥夺条件
只进程已获得的资源,在未使用之前,不能被剥夺,只能在使用完时由自己释放。
(4)环路等待条件
只在发生死锁时,必然在一个进程 – 资源的环形链,即进程集合{P0, P1, P2 …, Pn} 中的 P0 正在等待一个 P1 占用的资源;P1 正在等待 P2 占用的资源,…,Pn正在等待已被 P0 占用的资源。
问题四:如何避免死锁?
在有些情况下死锁是可以避免的。三种用于避免死锁的技术:
(1)加锁顺序(线程按照一定的顺序加锁)
(2)加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
(3)死锁检测
UNIX再学习 -- 线程同步_聚优致成的博客-CSDN博客

 浅谈linux的死锁检测 【转】 | 死锁 (lmlphp.com)

 (37条消息) 死锁-死锁预防、死锁避免(资源分配图与银行家算法)、死锁检测、死锁解除_Chieflion的博客-CSDN博客_资源分配图算法和银行家算法

 (37条消息) 操作系统-死锁(预防、安全序列、银行家算法图解、检测及解除)_YuanbaoQiang的博客-CSDN博客_死锁安全序列

1.死锁的产生以及解决方法

1.1什么是死锁?

  互斥锁是保护临界资源被线程间(或进程间)互斥的访问临界资源,当一个线程得到锁不释放时另一个线程申请时必须等待。当多个线程因为竞争资源而造成的一种僵局(互相等待),如果不施以援手,这些进程将永远等待。

 

内核态和用户态

一、内核态、用户态概念

当一个进程在用户空间运行时,称为该进程的用户态,当它落入内核空间时,称为该进程的内核态。

内核空间,是内核进程/线程所在的区域。主要负责运行系统、硬件交互。

用户空间,是用户进程/线程所在的区域。主要用于执行用户程序。

二、内核态和用户态的区别
内核态:运行的代码不受任何限制,CPU可以执行任何指令。

用户态:运行的代码需要受到CPU的很多检查,不能直接访问内核数据和程序,也就是说不可以像内核态线程一样访问任何有效地址。

操作系统在执行用户程序时,主要工作在用户态,只有在其执行没有权限完成的任务时才会切换到内核态。

三、为什么要区分内核态和用户态
保护机制。防止用户进程误操作或者是恶意破坏系统。内核态类似于C++的私有成员,只能在类内访问,用户态类似于公有成员,可以随意访问。

四、用户态切换到内核态的方式
1、系统调用(主动)

由于用户态无法完成某些任务,用户态会请求切换到内核态,内核态通过为用户专门开放的中断完成切换。

2、异常(被动)

在执行用户程序时出现某些不可知的异常,会从用户程序切换到内核中处理该异常的程序,也就是切换到了内核态。

3、外围设备中断(被动)

外围设备发出中断信号,当中断发生后,当前运行的进程暂停运行,并由操作系统内核对中断进程处理,如果中断之前CPU执行的是用户态程序,就相当于从用户态向内核态的切换。

TCP和UDP

1.TCP和UDP的区别?

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。它通过校验和,丢包时的重传控制,序号标识,滑动窗口、确认应答,次序乱掉的分包进行顺序控制实现可靠传输。即通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达; UDP尽最大努力交付,即不保证可靠交付。

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高要求的通信或广播通信场景。

4、每一条TCP连接只能是点到点的; UDP支持一对一,一对多,多对一和多对多的交互通信方式。

5、TCP对系统资源要求较多,UDP对系统资源要求较少


2.TCP协议中的三次握手和四次挥手过程?

三次握手:

(1)首先Client端发送连接请求报文,

(2)Server段接受连接后回复ACK报文,并为这次连接分配资源。

(3)Client端接收到ACK报文后也向Server段发送ACK报文,并分配资源,这样TCP连接就建立了。
四次挥手:

(1)假设Client端发起中断连接请求,也就是发送FIN报文。
(2)Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,“告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息”。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。
(3)当Server端确定数据已发送完成,则向Client端发送FIN报文,“告诉Client端,好了,我这边数据发完了,准备好关闭连接了”。
(4)Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,“就知道可以断开连接了”。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。
Ok,TCP连接就这样关闭了!

为什么连接的时候是三次握手,关闭的时候却是四次握手?

  答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

  答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

 

为什么TCP是可靠的?

  面试突击69:TCP 可靠吗?为什么? (baidu.com) 

 

UDP有时比TCP更有优势:

UDP以其简单、传输快的优势,在越来越多场景下取代了TCP, 如实时游戏。

(1)网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。

(2)TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP在内置的系统协议栈中,极难对其进行改进。

采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大。

基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题造成的影响。

什么是 ISO/OSI 网络协议模型?

 

 

内存管理

1.全局变量和局部变量在内存中的区别?
全局变量保存在内存的全局存储区中,占用静态的存储单元;局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
(没有说是静态全局和静态局部哦,否则就不是这种分布了)。
2.堆和栈的区别?
(1)堆栈空间分配区别
栈(操作系统):由操作系统(编译器)自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
(2)堆栈缓存方式区别
栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
(3)堆栈数据结构区别
堆(数据结构):堆可以被看成是一棵树,如:堆排序。
栈(数据结构):一种先进后出的数据结构。
存储空间布局:
历史沿袭至今,C 程序一直由下列几部分组成:

(1)正文段( text段/代码段)
这是由 CPU 执行的机器指令的部分。通常,正文段是可共享的,所以即使是频繁执行的程序(如文本编辑器,C 编译器和 shell 等)在存储器中也只需有一个副本,另外正文段常常是只读的,以防止程序由于意外而修改其指令。
正文段是用来存放可执行文件的操作指令,也就是说它是可执行程序在内存中的镜像。
(2)初始化数据段(数据段)
数据段用来存放可执行文件中已经初始化的全局变量,换句话说就是存放程序静态分配的变量和全局变量。
例如,C 程序中任何函数之外的声明:
int num = 10;
使此变量以其初值存放在初始化数据段中。
(3)未初始化数据段(bbs段)
bbs段包含了程序中未初始化的全局变量,在程序开始执行之前,内核将此段中的数据初始化为 0 或空指针。
例如:函数外的声明:
long sum[100];
使此变量存放在非初始化数据段中。
(4)堆
堆是用于存放进程进行中被动态分配的内存段,它大小并不固定,可动态扩张或缩减。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用 free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。 由于历史上形成的惯例, 堆位于未初始化数据段和栈之间 。
(5)栈
栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static 声明的变量,static 意味着在数据段中存放变量)。除此之外在函数调用结束后,函数的返回值也会被存放回栈中。由于栈的后进先出(LIFO)特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲我们可以把堆栈看成一个临时数据寄存,交换的内存区。
(6)参数和环境区
命令行参数和环境变量。

多路复用

(36条消息) UNIX再学习 -- 函数 select、poll、epoll_聚优致成的博客-CSDN博客

 

 

 

中断

简述嵌入式系统产生中断后,CPU响应中断大致分为几个阶段?

 

posted @ 2020-12-21 11:34  一个不知道干嘛的小萌新  阅读(122)  评论(0编辑  收藏  举报