在操作系统中,进程和线程都是执行的基本单位,但它们在性质和管理方面有所不同
进程
- 定义: 进程是一个正在运行的程序的实例,是操作系统资源分配的基本单位。
- 特点:
- 独立性:每个进程有其独立的内存空间、数据栈和其他辅助数据。
- 重量级:创建和管理进程需要较多的资源,相对较慢。
- 进程间通信(IPC)通常复杂。
线程
- 定义: 线程是进程中的一个执行流,是操作系统调度的基本单位。
- 特点:
- 轻量级:线程间切换比进程切换快,因为它们共享同一进程的内存和资源。
- 共享性:同属一个进程的线程可以直接访问进程的内存空间。
- 适合并行操作,提升性能。
在Linux系统下执行命令
1. 查看进程编号 (PID)
在Linux系统中,你可以使用ps -a
命令来查看当前系统中所有进程的编号(PID)。
ps -a
2. 终止一个进程
使用kill
命令可以终止指定的进程,你需要知道你想要终止的进程的PID。例如,如果你要终止PID为1234的进程,可以执行以下命令:
kill 1234
Linux的虚拟内存管理
虚拟内存管理
虚拟内存是操作系统提供的一种内存管理功能,它允许程序使用比实际物理内存大得多的内存空间。它的基本特性包括:
- 地址空间: 每个进程都被分配一个独立的虚拟地址空间,这样不同进程之间的内存不会相互干扰。
- 分页: 内存被分割成固定大小的页面,操作系统通过页面映射将虚拟地址转换为物理地址,允许程序在需要时加载或释放内存。
真实物理内存(内存映射)
在STM32等微控制器中,真实物理内存是直接可用的、预先分配的内存地址。这种内存通常是固定的,且没有动态分配的概念——每个外设和存储器都有其物理地址。在STM32中,内存映射允许程序直接访问硬件寄存器。
区别
- 地址空间: 虚拟内存使每个进程拥有独立的地址空间,而真实物理内存是共享的。
- 管理方式: 虚拟内存支持动态管理,制定和回收内存,而物理内存采用静态分配。
- 灵活性: 虚拟内存有助于内存保护和简化内存管理,而真实物理内存由于简单直接,通常响应速度更快。
理解Linux系统调用函数
在Linux中,系统调用是程序与操作系统内核进行交互的主要方式。常见的系统调用包括fork()
、wait()
、exec()
等。
1. fork()
- 功能: 创建一个新的进程,称为子进程。它是父进程的副本。
- 调用:
#include <unistd.h>
pid_t pid = fork();
if (pid == -1) {
// 错误处理
} else if (pid == 0) {
// 子进程代码
} else {
// 父进程代码
}
2. wait()
- 功能: 使父进程等待子进程的结束。
- 调用:
#include <sys/types.h>
#include <sys/wait.h>
wait(NULL); // 等待任意子进程结束
3. exec()
- 功能: 用新程序替换当前进程。
- 调用:
#include <unistd.h>
execlp("ls", "ls", NULL); // 执行ls命令
在阿里云服务器上编写C代码
- 远程登录: 使用Putty或Xterminal等工具,远程登录到分配的阿里云服务器Ubuntu系统。
- 创建目录:
mkdir ~/my_job
cd ~/my_job
- 使用Vi编辑器创建C文件:
vi example.c
在示例代码中你可以尝试以下内容(作为fork、wait和exec的例子):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
exit(1);
} else if (pid == 0) {
// 子进程
execlp("ls", "ls", NULL);
perror("Exec failed"); // 如果exec失败,程序会继续执行
exit(1);
} else {
// 父进程
wait(NULL); // 等待子进程结束
printf("Child finished\n");
}
return 0;
}
- 编译和运行:
gcc example.c -o example
./example
总结
通过实践对进程、线程、虚拟内存管理及Linux系统调用有了更深入的理解。这些知识是操作系统和计算机科学的基础,对于后续的编程和系统设计至关重要。希望大家能通过不断的练习掌握这些概念,并应用于实际项目中。