Linux系统调用编程

进程和线程

        进程是操作系统资源分配的基本单位,拥有独立的地址空间、内存、文件描述符等资源,进程间相互隔离。每个进程由程序代码、数据段和进程控制块(PCB)组成,PCB记录了进程状态、资源分配等信息。
         线程是进程内执行的最小单元,是CPU调度的基本单位。同一进程内的多个线程共享进程的资源(如内存、文件描述符),但每个线程有独立的运行栈和程序计数器。线程切换开销远小于进程,适合并发执行任务。

进程pid

    ps -a 命令会列出当前终端下所有进程的简要信息,包括进程PID。

        同时也可以使用ps -aux来查看详细的进程信息。

        同时我们也可以通过 kill 命令向指定 PID 发送信号终止进程。

 kill <PID>kill -15 <PID>:优雅终止进程,允许清理资源。kill -9 <PID>:强制终止进程(慎用,可能导致数据丢失)。

        同时也可以使用pkillkillall命令通过进程名终止进程(如 pkill python)。

虚拟内存管理

        Linux虚拟内存存可以为每个进程提供独立的4GB地址空间,进程访问的地址是虚拟的,需通过页表映射到物理内存或磁盘交换空间。
        其具有分页机制,能将内存和磁盘划分为固定大小的页,通过多级页表实现虚拟地址到物理地址的转换。同时可以进行动态管理,根据“最近最少使用”(LRU)算法,将不活跃的页面交换到Swap空间,释放物理内存供其他进程使用。还能进行进程隔离,每个进程的虚拟地址空间是独立的,可以防止内存越界访问,提升系统稳定性。
        同时他也兼具了扩展性、灵活性和安全性。当物理内存不足时,他会利用磁盘扩展虚拟内存,支持更多进程运行;同时程序可分配连续虚拟地址,无需关心物理内存碎片;还可以通过页表权限控制(如读写/执行位),隔离进程内存空间。

        STM32作为嵌入式MCU,采用物理内存直接映射,所有资源(Flash、SRAM、外设寄存器)都会统一编址到4GB线性地址空间。
        其具有固定地址分配,Flash代码区为0x08000000~0x0807FFFF(具体大小由芯片型号决定),SRAM数据区为0x20000000~0x2000XXXX(如STM32F103为64KB),外设寄存器:0x40000000~0x5FFFFFFF(如GPIO、UART等)。同时其所有数据需直接存储在物理内存中,无磁盘扩展机制。
        他可以直接访问物理地址,避免虚拟内存的页表查询开销,具有实时性;他内存容量小(通常KB级),需静态分配以避免碎片,资源会受到限制;同时他的内存映射由芯片设计决定,软件无法动态调整。

特性Linux虚拟内存STM32物理内存映射
地址空间每个进程独立4GB虚拟地址空间全局4GB物理地址空间,所有资源固定映射
内存管理动态分页、交换空间(Swap)静态分配,无交换机制
性能页表查询引入延迟,但支持大内存扩展直接访问物理地址,无额外开销
应用场景多任务通用操作系统嵌入式实时系统,资源受限环境
安全性进程隔离、权限控制无隔离机制,依赖硬件设计

系统调用函数

fork()

    fork()函数是Linux中创建新进程的核心系统调用,通过“写时复制”(Copy-on-Write, COW)技术生成一个与父进程几乎完全相同的子进程。子进程继承父进程的地址空间、文件描述符、信号处理等资源,但拥有独立的进程ID(PID)。调用方法如下:

 #include <unistd.h>pid_t fork(void);​// 返回值// 父进程返回子进程的 PID(正整数)。// 子进程返回 0。// 失败返回 -1(如资源不足)。// 子进程与父进程并发执行,顺序由调度器决定。// 文件描述符、内存页等资源默认共享,但写入时触发复制(COW)。

exec()

    exec()函数用于替换当前进程的映像,加载并执行新程序。成功调用后,原进程的代码、数据、堆栈等被完全覆盖,仅保留进程 ID。调用方法如下:

 #include <unistd.h>int execl(const char *path, const char *arg, ...);int execv(const char *path, char *const argv[]);​// 其他变体:execlp, execle, execvp, execve// path:可执行文件路径(如 /bin/ls)。// arg:命令行参数数组,以 NULL 结尾。// execlp/execvp:支持通过环境变量 PATH 搜索程序。// exec() 成功时不会返回,失败时返回 -1。// 子进程继承父进程的文件描述符,需手动关闭不需要的句柄。

wait()

    wait()函数用于父进程等待子进程终止,并回收其资源(避免僵尸进程)。通过获取子进程的退出状态,父进程可判断子进程是否正常结束及退出码。其调用方法如下:

 #include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);// 成功:返回终止子进程的 PID。// 失败:返回 -1(如无子进程)。// wait() 阻塞父进程直到子进程终止。// waitpid(pid, ...) 可指定等待特定子进程。

gcc编程

        这里我们在Linux系统下使用gcc实现一个系统调用函数的实现,首先我们进行对fork()函数的代码编写。

 #include <stdio.h>#include <unistd.h>  // 包含fork()的头文件#include <sys/types.h>​int main() {pid_t pid = fork();  // 创建子进程​if (pid < 0) {// fork失败perror("fork failed");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d", getpid());execlp("/bin/ls", "ls", "-l", NULL);  // 子进程执行ls命令} else {// 父进程printf("Parent process: PID = %d, Child PID = %d", getpid(), pid);sleep(2);  // 等待子进程结束}​return 0;}

        然后我们在写代码的目录下新建一个CMakeLists.txt文件以进行cmake编程。

 cmake_minimum_required(VERSION 3.10)project(fork_test)# 添加可执行文件add_executable(fork_test fork_test.c)# 显式链接pthread库target_link_libraries(fork_test pthread)#指定gcc编译器set(CMAKE_C_COMPILER gcc)

        接着我们在建立一个“build”文件夹来生成构建文件,并进行编译。

 mkdir buildcd buildcmake ..make

        然后就可以输入./fork_test来运行程序了。

总结

        本次实验对Linux系统调用编程进行了练习,进一步了解了进程和内存管理,并调用了fork()函数,理解了内存机制差异,有助于后续选择更合适的系统设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣hot100题】(054)全排列

挺经典的回溯题的。 class Solution { public:vector<vector<int>> result;void recursion(vector<int>& nums,vector<int>& now){if(nums.size()0){result.push_back(now);return ;}for(int i0;i<nums.size();i){now.push_back(nums[i]);…

【Ragflow】11. 文件解析流程分析/批量解析实现

概述 本文继续对ragflow文档解析部分进行分析&#xff0c;并通过脚本的方式实现对文件的批量上传解析。 文件解析流程 文件解析的请求处理流程大致如下&#xff1a; 1.前端上传文件&#xff0c;通过v1/document/run接口&#xff0c;发起文件解析请求 2.后端api\apps\docum…

2024年零知识证明(ZK)研究进展

Sumcheck 整个领域正在转向更多地依赖于 Sumcheck Protocol Sumcheck是用于验证多项式承诺的协议,常用于零知识证明(ZKP)中,尤其是在可验证计算和扩展性上。它的主要目的是通过对多项式进行分段检查,从而保证某个多项式在给定输入上的正确性,而不需要直接计算出整个多项…

thinkphp每条一级栏目中可自定义添加多条二级栏目,每条二级栏目包含多个字段信息

小程序客户端需要展示团购详情这种结构的内容,后台会新增多条套餐,每条套餐可以新增多条菜品信息,每条菜品信息包含菜品名称,价格,份数等字段信息,类似于购物网的商品多规格属性,数据表中以json类型存储,手写了一个后台添加和编辑的demo 添加页面 编辑页面(json数据…

Vue3引入ElementPlus

1.ElementPlus属于第三方的应用框架&#xff0c;官网地址&#xff1a;设计 | Element Plus &#xff0c;学习可以参考该网站的指南。 2.安装element-plus &#xff0c;指令为&#xff1a;npm install element-plus --save 3.引入elementplus的全局&#xff0c;组件、样式、图标…

react+antd封装一个可回车自定义option的select并且与某些内容相互禁用

需求背景 一个select框 现在要求可多选 并且原有一个any的选项 其他选项为输入后回车自己增加 若选择了any 则其他选项不可选择反之选择其他选项any不可选择 并且回车新增时也不可直接加入到选中数组只加入到option内 并且不可重复添加新内容 实现过程 <Form.Item …

Oracle数据库数据编程SQL<8 文本编辑器Notepad++和UltraEdit(UE)对比>

首先&#xff0c;用户界面方面。Notepad是开源的&#xff0c;界面看起来比较简洁&#xff0c;可能更适合喜欢轻量级工具的用户。而UltraEdit作为商业软件&#xff0c;界面可能更现代化&#xff0c;功能布局更复杂一些。不过&#xff0c;UltraEdit支持更多的主题和自定义选项&am…

【学Rust写CAD】30 Alpha256结构体补充方法(alpha256.rs)

源码 impl Alpha256 {#[inline]pub fn alpha_mul(&self, x: u32) -> u32 {let mask 0xFF00FF;let src_rb ((x & mask) * self.0) >> 8;let src_ag ((x >> 8) & mask) * self.0;(src_rb & mask) | (src_ag & !mask)} }代码分析 功能 输…

Linux systemd 服务全面详解

一、systemd 是什么&#xff1f; systemd 是 Linux 系统的现代初始化系统&#xff08;init&#xff09;和服务管理器&#xff0c;替代传统的 SysVinit 和 Upstart。它不仅是系统启动的“总指挥”&#xff0c;还统一管理服务、日志、设备挂载、定时任务等。 核心作用 服务管理…

jetson AGX orin--ARM64 换源报错Packages 404 Not Found [IP: 2402:f000:1:400::2 443]

问题 原因&#xff1a; ARM64结构不能使用X86结构的源&#xff0c;清华源不完全支持ARM64。使用下面这个源 sudo vim /etc/apt/sources.list 删掉原来的&#xff0c;改成这个 # ARM64 架构专用源 deb [archarm64] http://ports.ubuntu.com/ubuntu-ports focal main restrict…

ARM 性能分析工具:Streamline

文章目录 1. 前言2. 安装2.1 在 Host 安装 Arm Performance Studio2.2 在 ARM 目标平台安装 gatord 3. 使用3.1 离线方式3.2 在线方式3.3 添加符号表 4. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不…

React: hook相当于函数吗?

一、Hook 是一个函数&#xff0c;但不仅仅是函数 函数的本质 Hook 确实是一个 JavaScript 函数&#xff0c;例如 useState、useEffect 或自定义 Hook 都是函数。它们可以接受参数&#xff08;如初始状态值或依赖项数组&#xff09;&#xff0c;并返回结果&#xff08;如状态值和…

Android学习总结之算法篇三(排序)

归并排序原理 归并排序&#xff08;Merge Sort&#xff09;是一种采用分治法&#xff08;Divide and Conquer&#xff09;的排序算法&#xff0c;其基本思想是将一个大问题分解为多个小问题&#xff0c;分别解决这些小问题&#xff0c;然后将小问题的解合并起来得到原问题的解…

Python列表(List)深度解析

列表(List)是Python中最基础且强大的数据结构之一&#xff0c;但它的底层实现和特性远比表面看起来复杂。本文将深入探讨列表的各个方面。 1. 列表基础特性 1.1 可变序列类型 lst [1, 2, 3] lst[1] 20 # 可变性1.2 异构容器 mixed [1, "hello", 3.14, [1, 2]…

Java基础-设计模式详解

摘要&#xff1a;设计模式是软件工程中解决常见问题的经典方案。本文结合Java语言特性&#xff0c;深入解析常用设计模式的核心思想、实现方式及实际应用场景&#xff0c;帮助开发者提升代码质量和可维护性。 一、设计模式概述 1.1 什么是设计模式&#xff1f; 设计模式&…

Docker 构建镜像异常报错解决

报错一&#xff1a; # 启动 SSH Agent eval $(ssh-agent -s)# 添加私钥到 agent (替换为你的实际密钥路径) ssh-add ~/.ssh/id_ed25519# 验证密钥已加载 ssh-add -L# 查看 SSH_AUTH_SOCK 是否设置 echo $SSH_AUTH_SOCK # 应输出类似&#xff1a;/tmp/ssh-XXXXXX/agent.XXXX# 显…

动态规划似包非包系列一>组合总和IIV

目录 题目分析&#xff1a;状态表示&#xff1a;状态转移方程&#xff1a;初始化填表顺序返回值&#xff1a;代码呈现&#xff1a; 题目分析&#xff1a; 状态表示&#xff1a; 状态转移方程&#xff1a; 初始化填表顺序返回值&#xff1a; 代码呈现&#xff1a; class Soluti…

Linux下调试器gdb_cgdb使用

文章目录 一、样例代码二、使用watchset var确定问题原因条件断点 一、样例代码 #include <stdio.h>int Sum(int s, int e) {int result 0;int i;for(i s; i < e; i){result i;}return result; }int main() {int start 1;int end 100;printf("I will begin…

JSON Crack:简化数据可视化的参数编辑器

简介 在当今数据驱动的世界中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;广泛应用于各种开发和数据分析场景。然而&#xff0c;复杂的JSON数据往往难以阅读和理解&#xff0c;特别是在数据量庞大时&#xf…

PostgreSQL 删除数据库

PostgreSQL 删除数据库 概述 PostgreSQL 是一款功能强大的开源关系型数据库管理系统&#xff0c;它提供了丰富的功能和强大的性能。在数据库管理过程中&#xff0c;有时需要删除不再需要的数据库&#xff0c;以释放资源或进行数据库维护。本文将详细介绍如何在 PostgreSQL 中…