- Linux 进程与线程(task)
- 1. 何为进程和线程?
- 2. Linux 如何表示进程与线程?
- 3. 系统调用 fork() 和 exec()
- 4. linux 一切皆文件,那文件如何将上述概念串联起来?
- 参考文献
Linux 进程与线程(task)
1. 何为进程和线程?
1.1 二进制程序
- 二进制程序:指保存在存储介质(磁盘等)上的程序,以给定操作系统(windows、linux等)和计算机体系结构(x86等)可访问的格式(编译生成,比如 windows exe 和 Linux elf 文件格式)。可以运行但尚未开始。
1.2 进程
- 进程:是操作系统对运行的二进制程序的抽象,包括:加载的二进制程序、虚拟内存、内核资源(如打开的文件列表、关联的用户)等。
1.3 线程
- 线程:是进程内的执行单元。
2. Linux 如何表示进程与线程?
2.1 在 Linux 中,内核用 task_struct 这一种数据结构代表进程、线程。
Everything is simply a runnable task
2.2 在 Linux 中,无论是进程还是线程,本质上都是通过 clone 一个已存在 task (进程\线程) 实现的,两者的差别就在于 clone 时 参数的传递。
fork — 进程创建,通过调用 0 共享的 clone 实现
pthread_create — 线程创建,通过调用 最大共享 的 clone实现
2.3 在 Linux 中,top 和 ps 命令对 pid 的理解不一致
ps 文档 (ps 用来查看进程信息(执行命令时进程的快照))
top 文档 (监控各进程占CPU 内存信息)
2.4 常用命令
查看所有进程 ps -aux
查找特定进程 ps -ef | grep "进程相关信息"
例如:获取进程 pid
# 获取PID
PID=$(ps -ef |grep “${JRE_HOME}/bin/java -jar ${APP_HOME}/${APP_NAME}” |grep -v grep |awk '{print $2}')
3. 系统调用 fork() 和 exec()
3.1 进程地址空间
32 bit
section 一般指 elf 文件的分段, segment 指的是 进程地址空间的分段。
3.2 示例
forkProcess.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
// make two process which run same program after this instruction
// parent process return child process pid
// child process return 0
pid = fork();
if(pid > 0){
printf("I am the parent of pid = %d \n",pid);
}else if(!pid){
printf("I am the child \n");
}else if(pid == -1){
perror("fork");
}
return 0;
}
运行结果:
fork 产生一个新的子进程,和父进程共享代码段(写时复制—copy on write,提升内存利用率),若子进程需要装载其它的二进制程序,则需用到 exec 函数。
4. linux 一切皆文件,那文件如何将上述概念串联起来?
- 进程级别文件描述符表。
- 系统级别打开文件表。
- 磁盘的 i-node 表,内核一般会存放一个副本在内存中。