目录
一. 理解进程和线程的概念。并在Linux系统下进行相应操作
1.1概念
1.1.1进程(Process)
1.1.2 线程(Thread)
1.2操作
1.2.1用 ps -a 命令查看系统中各进程的编号pid
1.2.2用kill 命令终止一个进程pid
二. 解释Linux的“虚拟内存管理”,它与stm32中的 真实物理内存(内存映射)有什么区别?
2.1核心区别
2.2地址空间
2.3内存分配
2.4典型特征
2.5适用场景
三. 理解 Linux系统调用函数 fork()、wait()、exec() 等的含义和调用方法 。
3.1用putty或xterminal等工具软件进行操作。
3.1.1打开xterminal,连接服务器
3.1.2在home目录下创建工作目录
3.1.3使用vi创建C程序文件
3.1.4按i进入编辑模式,输入以下代码:
3.1.5使用gcc编译和运行程序
3.2在各小组的树莓派中,也手动创建组员的账号,组员在各自的账号+home目录下,完成同样的Linux系统调用函数练习。
3.2.1登录树莓派,打开端口进行账号密码的创建
3.2.2登录对应账号后进行编辑程序然后运行
一. 理解进程和线程的概念。并在Linux系统下进行相应操作
1.1概念
1.1.1进程(Process)
定义:
进程是操作系统进行资源分配和调度的基本单位
是程序的一次执行过程,具有独立的内存空间
核心特征:
独立性:每个进程有独立的地址空间
动态性:进程有创建、执行、暂停、终止等生命周期
并发性:多个进程可以并发执行
资源分配单位:CPU、内存等资源以进程为单位分配
进程组成:
代码段(text)
数据段(data)
堆(heap)
栈(stack)
进程控制块(PCB)
Linux中的进程:
ps -aux # 查看系统所有进程
top # 动态查看进程状态
1.1.2 线程(Thread)
定义:
线程是进程内的执行单元,是CPU调度的基本单位
一个进程可以包含多个线程,共享进程的资源
核心特征:
轻量级:创建/销毁开销比进程小
共享性:同一进程的线程共享内存和资源
独立性:有独立的执行路径和栈空间
并发性:多线程可并发执行
线程组成:
线程ID
程序计数器
寄存器集合
栈空间
Linux中的线程
ps -T -p <PID> # 查看特定进程的线程
top -H # 显示线程信息
1.2操作
1.2.1用 ps -a 命令查看系统中各进程的编号pid
1.2.2用kill 命令终止一个进程pid
因为终止一个进程需要权限所以如果之输入
kill 240932
并不会成功
这里就需要输入来获得权限,就可以了
sudo kill 2409326
然后再用ps -a 命令查看系统中各进程的编号pid可以发现,已经成功终止
二. 解释Linux的“虚拟内存管理”,它与stm32中的 真实物理内存(内存映射)有什么区别?
2.1核心区别
Linux使用虚拟内存(通过MMU实现地址转换),STM32使用物理内存直接映射(无MMU)
Linux有内存保护机制(用户/内核态隔离),STM32所有代码均可访问全部内存
2.2地址空间
Linux:每个进程有独立的4GB(32位)虚拟地址空间
STM32:所有程序共享固定的物理地址空间(如Flash 0x08000000,SRAM 0x20000000)
2.3内存分配
Linux:动态分配(malloc→brk/sbrk/mmap)
STM32:静态分配(链接脚本确定,需手动管理)
2.4典型特征
Linux支持:
内存超额使用(Swap)
写时复制(COW)
内存共享(共享库)
STM32特征
确定性访问(无地址转换延迟)
直接硬件操作(寄存器映射)
无内存碎片风险(静态分配)
2.5适用场景
选择Linux虚拟内存:需要多进程隔离、运行大型程序、内存需求超过物理内存时
选择STM32物理映射:实时控制系统、资源受限(<1MB内存)场景、需要直接操作寄存器时
三. 理解 Linux系统调用函数 fork()、wait()、exec() 等的含义和调用方法 。
3.1用putty或xterminal等工具软件进行操作。
远程登录自己被分配的阿里云服务器Ubuntu系统的账号(见下面附件),在自己的home目录下,创建一个作业子目录,然后学习使用vi 编辑一个c代码,gcc编译,实现一个系统调用函数的例子
3.1.1打开xterminal,连接服务器
3.1.2在home目录下创建工作目录
cd ~//判断是否在home目录
mkdir week6//创建一个名为week6的子目录
cd week6//进入子目录week6
3.1.3使用vi创建C程序文件
vi process.c//创建一个名为process.c的c文件并进入
3.1.4按i
进入编辑模式,输入以下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {printf("=== 系统调用演示程序 ===\n");printf("主进程PID: %d\n", getpid());// 1. fork()示例pid_t pid = fork();if (pid < 0) {perror("fork失败");return 1;}if (pid == 0) {// 子进程代码块printf("\n子进程运行中 (PID: %d)\n", getpid());// 2. exec()示例 - 执行ls命令printf("准备执行ls命令...\n");execl("/bin/ls", "ls", "-l", NULL);// 如果exec执行成功,以下代码不会运行perror("exec失败");return 1;} else {// 父进程代码块printf("\n父进程 (PID: %d) 创建了子进程 (PID: %d)\n", getpid(), pid);// 3. wait()示例printf("父进程等待子进程结束...\n");int status;wait(&status);if (WIFEXITED(status)) {printf("\n子进程退出状态: %d\n", WEXITSTATUS(status));}}printf("程序执行结束\n");return 0;
}
按ESC键退出编辑模式,输入:wq
保存并退出vi。
3.1.5使用gcc编译和运行程序
gcc process.c -o week6//prcess.c为创建的c文件名称 week6为之前创建的子目录名称
./week6
运行结果如下:
3.2在各小组的树莓派中,也手动创建组员的账号,组员在各自的账号+home目录下,完成同样的Linux系统调用函数练习。
3.2.1登录树莓派,打开端口进行账号密码的创建
创建组
sudo groupadd team//team为组的名称
创建账号
sudo useradd -m -G team -s /bin/bash maxy//maxy为创建的用户名称
设置对应账户的密码
echo "member1:password1"//member1为设置密码的用户名称 password1为要设置的密码
3.2.2登录对应账号后进行编辑程序然后运行
登录账号
ssh member1@树莓派IP地址
# 输入密码password1
创建子目录
mkdir test//创建子目录 test为创建子目录的名称
cd test//登录子目录
编辑程序代码
nano week6.c//week6.c为文件的名称
输入代码
// process_demo.c
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>int main() {printf("[%d] Parent process starts\n", getpid());pid_t pid = fork();if (pid < 0) {perror("Fork failed");return 1;} else if (pid == 0) {printf("[%d] Child process running\n", getpid());execl("/bin/ls", "ls", "-l", NULL);perror("Exec failed");return 1;} else {printf("[%d] Parent waiting for child %d\n", getpid(), pid);int status;wait(&status);if (WIFEXITED(status)) {printf("[%d] Child exited with status %d\n", getpid(), WEXITSTATUS(status));}}printf("[%d] Process ends\n", getpid());return 0;
}
编译程序
gcc -Wall -Wextra week6.c -o test//week6.c为程序代码的文件名称 test为前面创建的子目录
运行程序
./test//./为运行 test为运行文件的子目录
运行成功