《Linux嵌入式实时应用开发实战(原书第3版)》——3.4 Linux进程模型
本节书摘来自华章计算机《Linux嵌入式实时应用开发实战(原书第3版)》一书中的第3章,第3.4节,作者:(美)Doug Abbott 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.4 Linux进程模型Linux中的基本结构元素是进程,由可执行代码和如数据、文件描述符等组成的资源组合组成。这些资源完全是受保护的,因此一个进程不能直接访问另一个进程的资源。为了使两个进程相互通信,它们必须使用Linux定义的中间进程通信机制,如共享存储区域或管道。
由于它在系统中建立了一个高级别的保护,所以工作良好。错误的进程会被系统检测出来并在它对其他进程造成破坏前将其抛出(图3-7)。但是在创建进程时的过度开销和使用中间进程通信机制的代价是昂贵的。
一个线程只有代码。线程只存在于进程内部,一个进程中的所有线程都共享资源。因此所有的线程都可以同样地访问数据存储器和文件描述符。这个模型有时叫做轻量级多任务以与UNIX/Linux进程模型区分。
轻量级任务的优点是中间线程的通信更有效。它的缺点是任何线程都可以破坏其他线程的数据。多数的RTOS都曾经有类似轻量型的模型。当然最近几年,存储器保护的硬件花费明显下降,因此一些RTOS供应商开始提供他们系统的保护模式版本,这看起来像Linux进程模型。
3.4.1 fork()函数
Linux的生命从一个进程开始,这就是在启动时创建的init进程。系统中其他进程的创建都是通过调用fork()实现的。调用fork()的进程叫父进程,新创建的进程叫子进程。所以每个进程都有父和子,这取决于谁创建谁。
如果你是在一个多任务的操作系统中,这里的任务是函数通过调用任务创建服务生成的,那么fork进程看起来显然很奇怪。fork()函数创建一个父进程的副本——代码、数据、文件描述符和父进程目前拥有的其他任何资源。这可能会增加MB量级存储空间的复制。为避免复制许多可能被覆盖的东西,Linux引入了一个写时复制的策略。
fork()函数从复制进程数据结构和给子进程一个新的进程标识符(PID)开始。然后,复制一个页目录和页表。最开始,PTE均与父进程一样指向相同的物理页面。两个进程的所有页面都设置为只读。当其中的某一个进程试图写时,会引起一个页面错误。这会让Linux给该进程分配一个新页面,并复制现有页面的内容。
因为两个进程都执行同样的代码,所以它们都从fork()的返回值继续执行(这就是为什么很奇怪)。为了区分父进程和子进程,fork()给子进程返回一个函数值0,但是给父进程返回子进程的PID值。表3-1就是fork函数调用的一个小例子。
3.4.2 execve()函数
当然,99%的时间里都是子进程通过调用execve()激活一个新的程序来从磁盘导入一个可执行镜像文件。表3-2给出了一个简单的命令行注释器的架构形式。它从stdin读入一行文本,解析后调用fork()函数创建一个新进程。然后子进程调用execve()导入一个文件并执行之前输入的命令。execve()覆盖了调用进程的代码、数据和堆栈段。
"
如果这是普通的前景命令,则命令解释器必须等到命令执行完毕。这是通过waitpid()来完成的,该函数阻塞调用进程直到与pid参数匹配的进程结束。注意,大部分的多任务操作系统没有能力阻塞一个挂起了另一个进程的进程或任务。
如果execve()成功了,它没有返回值,而是将控制传递至新载入的程序。
【直播回顾】Java Spring Boot开发实战系列课程(第17讲):Spring Boot 2.0实战Docker容器Linux Docker是最流行的开源容器引擎,Go语言开发,在互联网大规模集群、云计算、微服务等架构中广泛使用。本次课程一起学习如何基于Linux系统实战实战Docker容器,打包Spring Boot2.0应用。
《Linux嵌入式实时应用开发实战(原书第3版)》—— 导读 ,Linux世界又发生了很多变化,这也是本书再版的一个直接原因。Linux内核持续改进,为了庆祝20周年,最近提高到了3.0版。2007年年底,谷歌引入了安卓系统。据统计,截至2011年8月,安卓占有智能手机市场48%的份额,每天有500 000台设备被激活。
相关文章
- Linux文件共享(二)——两个独立进程打开同一个文件
- Linux安装telnet
- [Linux] linux awk命令详解
- Linux为用户设定环境变量
- 【Linux】嵌入式开发,在Linux中使用C语言对Fork函数执行子函数及父函数,命令ps 及 ls 操作
- 在Linux中使用线程
- Linux rm删除大批量文件
- 【刷题】面筋-linux 如何将文件从一台服务器转移到另一台服务器
- Linux错误代码含义
- linux内核数据结构之链表
- linux中使用lftp上传下载文件
- Linux系统调优详解(六)——网络状态查看命令nload
- VMWare软件linux虚拟机安装Ubuntu&BIOS设置
- linux驱动开发重点关注内容--摘自《嵌入式Linux驱动模板精讲与项目实践》
- 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )
- 【Linux 内核】进程管理 - 进程优先级 ① ( 限期进程 | 实时进程 | 普通进程 | 进程优先级相关字段 )
- Linux pipe函数
- L86.linux命令每日一练 -- 第12章 Linux系统常用内置命令(二)
- L81.linux命令每日一练 -- 第11章 Linux系统管理命令 -- ethtool和mii-tool
- L47.linux命令每日一练 -- 第七章 Linux用户管理及用户信息查询命令 -- users和whoami
- 嵌入式linux开发,交叉编译tslib-1.22时报错:configure:13646: error: possibly undefined macro: AC_MSG_ERROR
- 嵌入式linux开发,FFmpeg移植,ffmpeg-4.3.2.tar.gz移植,ffmpeg-3.4.11
- 嵌入式linux开发,抓包工具tcpdump使用方法
- 嵌入式linux开发,多个rtc实时时钟读取、写入操作命令
- 嵌入式linux开发,将新创建文件存储于linux内存中
- linux===给新手的 10 个有用 Linux 命令行技巧(转)
- Linux:内存访问问题检查工具valgrind
- 【linux】Linux操作系统常用指令大全
- 嵌入式Linux开发,Ubuntu22下交叉编译内核报错: multiple definition of `yylloc‘; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0
- 嵌入式linux开发,在cmake命令中配置交叉编译
- 嵌入式linux开发,libre库移植
- 嵌入式linux开发,配置uboot报错:<command-line>:0:12: fatal error: curses.h: No such file or directory
- 嵌入式Linux开发,去掉内核kernel开机画面logo屏幕上的打印信息