【应用】04.Linux进程与进程间通信
【嵌入式八股】一、语言篇https://www.nowcoder.com/creation/manager/columnDetail/mwQPeM
【嵌入式八股】二、计算机基础篇https://www.nowcoder.com/creation/manager/columnDetail/Mg5Lym
【嵌入式八股】三、硬件篇https://www.nowcoder.com/creation/manager/columnDetail/MRVDlM
【嵌入式八股】四、嵌入式Linux篇(本专栏)https://www.nowcoder.com/creation/manager/columnDetail/MQ2bb0
3、Linux进程与进程间通信
基础
63.PCB进程控制块
Linux PCB(Process Control Block)是操作系统中的一个数据结构,用于存储和管理进程的运行状态信息。每个正在运行的进程都有一个对应的PCB,包含了进程的重要信息,如进程ID、状态、优先级、内存地址、打开的文件列表等。当操作系统需要切换进程时,它会使用PCB中的信息来保存当前进程的状态,并将下一个要执行的进程的状态装入PCB中,然后进行上下文切换,以实现多任务并发执行。
在Linux系统中,每个进程都有一个唯一的PID(Process ID),由内核为其分配。每个进程的PCB在内核中被存储为一个结构体,可以通过系统调用或/proc文件系统访问PCB的信息。Linux PCB也被称为进程描述符(Process Descriptor),是Linux操作系统中非常重要的数据结构之一。
Linux PCB(Process Control Block)主要包含以下内容:
- 进程ID(PID):唯一标识进程的数字。
- 进程状态(State):描述进程当前的运行状态,如运行、就绪、等待等。
- 进程优先级(Priority):用于决定进程在竞争CPU资源时的优先级。
- 程序计数器(Program Counter,PC):记录了下一条将要执行的指令在内存中的地址。
- 寄存器(Registers):存储进程的运行状态,如通用寄存器、程序状态字、堆栈指针等。
- 内存管理信息(Memory Management Information):记录了进程的内存使用情况,如内存分配情况、页表等。
- 打开文件列表(Open File List):记录了进程打开的文件和I/O设备。
- 进程所属用户(User):记录了进程所属的用户和用户组。
- 进程间通信(Interprocess Communication,IPC)信息:记录了进程间通信的方式和状态。
64./proc目录下,以数字命名的目录表示什么?:heart:
在Linux系统中,/proc目录是一个虚拟文件系统,它提供了一种访问内核数据结构和系统信息的方式。/proc目录下的以数字命名的目录表示系统中正在运行的进程的PID(进程ID),每个数字目录对应一个正在运行的进程。例如,/proc/1234目录表示进程ID为1234的进程。
这些数字目录中包含了该进程的各种信息,包括进程的状态、命令行参数、文件句柄、内存映射、CPU时间、网络连接等等。这些信息以文件的形式存在于数字目录中,可以使用cat等命令读取和查看。
/proc目录下的数字目录提供了一种方便的方式来查看和监控进程的运行状态和系统的运行情况,对于系统管理和调试都非常有用。
65.进程的地址空间模型?
[进程地址空间详解_小赵小赵福星高照~的博客-CSDN博客](
data segment | 存储初始化不为0的全局变量和静态变量、const型常量。 |
bss segment | 存储未初始化的、初始化为0的全局变量和静态变量。 |
heap(堆) | 用于动态开辟内存空间。 |
memory mapping space(内存映射区) | mmap系统调用使用的空间,通常用于文件映射到内存或匿名映射(开辟大块空间),当malloc大于128k时(此处依赖于glibc的配置),也使用该区域。在进程创建时,会将程序用到的平台、动态链接库加载到该区域。 |
stack(栈) | 存储函数参数、局部变量。 |
kernel space | 存储内核代码。 |
66.创建进程有哪几种方式?
- fork()系统调用:fork()是Unix/Linux系统中用于创建子进程的系统调用。调用fork()时,系统会复制当前进程的一个副本,并在副本上运行子进程。子进程是父进程的一个副本,但有自己的进程ID,并独立于父进程运行。使用fork()创建的进程通常称为子进程。
- exec()系统调用:exec()系统调用可以用来加载并运行一个新的程序。它会将当前进程替换为新程序的代码和数据,并开始运行该程序。使用exec()系统调用创建的进程可以看作是原进程的替身。
- 系统启动时创建:当操作系统启动时,内核会自动创建一些进程,例如init进程。这些进程通常是系统的核心进程,负责启动和管理其他进程。
- 通过库函数创建:在某些编程语言中,如Python,C++等,可以通过调用库函数来创建进程,例如在Python中可以使用multiprocessing库创建进程。
父进程、子进程、进程组、作业和会话
67.分别介绍父进程、子进程、进程组、作业和会话
- 父进程:当一个进程被创建时,它会由一个已存在的进程(即父进程)创建。父进程是新创建进程的直接控制者,它可以监视、管理和控制子进程的运行。父进程可以与子进程共享信息和资源,也可以在需要时向子进程发送信号或其他指令。
- 子进程:子进程是由父进程创建的进程,它拥有独立的内存空间和资源。子进程可以执行不同的任务,或在父进程的指导下完成某些操作。子进程可以继承父进程的一些属性和资源,如环境变量、文件描述符等。
- 进程组:进程组是由一个或多个相关联的进程组成的集合。每个进程组都有一个唯一的进程组ID(GID),并且每个进程都属于一个进程组。进程组可以方便地对多个进程进行管理和控制,比如向整个进程组发送信号、挂起或恢复进程组等操作。
- 作业:一个作业是由一个或多个进程组成的一组任务。通常,一个作业由一个前台进程组和一个或多个后台进程组组成。前台进程组通常是用户当前正在交互的任务,而后台进程组则是在后台运行的任务。作业可以被挂起、恢复、终止等操作。
- 会话:一个会话是一个或多个进程的集合,这些进程共享同一个控制终端。当用户登录到一个系统时,系统会自动创建一个会话,该会话通常包含一个或多个进程组。会话可以管理和控制与终端相关的操作,如控制终端的输入和输出、接受和发送信号等操作。
68.为什么只能运行一个前台作业?
Linux其实并没有限制同时运行多个前台作业,只是在命令行模式下,一个终端窗口只能接受一个前台作业的输入,因此看起来好像只能运行一个前台作业。
实际上,Linux可以同时运行多个作业,包括前台作业和后台作业。前台作业指的是需要在命令行界面进行输入和输出的作业,后台作业则是在后台运行的作业,不需要在命令行界面进行交互。
如果要在同一个终端窗口中运行多个前台作业,可以使用作业控制命令来管理,如"fg"和"bg"命令可以将后台作业转换为前台作业,或将前台作业转换为后台作业,从而实现同时运行多个作业的目的。
此外,也可以通过使用多个终端窗口或者终端会话来同时运行多个前台作业,从而避免在同一个终端窗口中只能运行一个前台作业的限制。
69.作业与进程组的区别:
作业和进程组之间的主要区别在于作业是用户在终端或命令行上输入的一组命令,而进程组是操作系统中相关的进程的集合。作业可以包含多个进程,并且可以是前台或后台作业,而进程组中的进程通常是由同一个父进程创建的,并且可以共享同一个终端或伪终端。
如果作业中的某个进程有创建了子进程,则该子进程是不属于该作业的。 一旦作业运行结束,shell就把自己提到前台(子进程还存在,但是子进程不属于作业),如果原来的前台进程还存在(这个子进程还没有终止),他将自动变为后台进程组。
70.fork函数
Linux中的fork()函数是一个创建新进程的系统调用。它会复制当前进程的一个副本,并且在新的进程中运行。这个新进程被称为子进程,而原始进程被称为父进程。父进程和子进程是通过进程ID来区分的。
当调用fork()函数时,操作系统会创建一个新的进程,并将所有的内存、寄存器和文件描述符等信息复制到这个新的进程中。父进程和子进程会在fork()函数的返回值上得到不同的结果。在父进程中,fork()会返回子进程的进程ID,而在子进程中,fork()会返回0。如果fork()返回-1,则表示创建新进程失败。
使用fork()函数可以实现多进程编程,这样可以在同一个程序中同时执行多个任务,从而提高程序的效率。例如,在Web服务器中,当有多个客户端请求时,可以通过fork()函数创建多个子进程来同时处理这些请求。
71.请你回答一下fork和vfork的区别?
- 父进程的行为不同:
- 在fork中,父进程会在创建子进程之后恢复执行,并且可以通过子进程的PID值来确定子进程是否已经创建成功。
- 在vfork中,父进程会暂停执行,直到子进程调用_exit或exec函数之后才会恢复执行。因为子进程共享父进程的地址空间,所以在子进程执行之前,父进程不能修改共享的数据。
- 子进程的行为不同:
- 在fork中,子进程会拥有父进程的副本,可以通过fork返回值来判断自己是父进程还是子进程,并且可以在自己的地址空间中修改自己的数据。
- 在vfork中,子进程会共享父进程的地址空间,因此在子进程执行期间,父进程和子进程共享同一份地址空间,直到子进程调用exec或_exit函数之后,才会创建自己的独立地址空间。
- 效率不同:
- 在fork中,操作系统需要为子进程创建独立的地址空间,并将父进程的所有资源复制一份,因此fork的开销比较大。
- 在vfork中,操作系统不需要复制父进程的所有资源,而是在父进程的地址空间中创建一个新的子进程,因此vfork的开销比fork小。
72.系统调用获取进程ID
- **getpid():**查找唯一的进程ID。
- **getppid():**查找唯一的父进程ID。
73.子进程从父进程继承的资源有哪些?
父子进程共享哪些内容
父进程fork出子进程,父进程中的变量和子进程中的变量有什么区别?>
父子进程相同:
刚fork后。 data段、text段、堆、栈、环境变量、全局变量、宿主目录位置、进程工作目录位置、信号处理方式(0-3G的用户空间)
父子进程不同:
进程id、返回值、各自的父进程、进程创建时间、闹钟、未决信号集。
父子进程共享:
读时共享、写时复制。———————— 全局变量。
1.文件描述符(打开文件的结构体) 2. mmap映射区(进程间通信)。
74.fork()一子进程程后,父进程的全局变量能不能使用?
读时共享和写时复制是两个常见的操作系统技术,用于减少资源的浪费和提高性能。
读时共享指的是,在多个进程或线程之间共享同一个资源(如内存),但是在修改该资源之前先进行一次拷贝,从而保证了资源在读取时的共享,而在修改时的独立性。这样,当多个进程或线程共享一个资源时,只需要在需要修改该资源时才进行拷贝,而不是在每次读取时都进行拷贝。这种方法可以有效地减少资源的浪费,提高系统性能。
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
查阅整理上千份嵌入式面经,将相关资料汇集于此,主要包括: 0.简历面试 1.语言篇 2.计算机基础 3.硬件篇 4.嵌入式Linux【本专栏】 (建议PC端查看)