在学习这部分之前,我对Linux系统基本不了解,只是做一些简单的工作,使用一些常见命令,使用Makefile编译工程,做arm交叉编译等。
所以这部分内容也会对用到的相关内容做一些总结。这篇总结有点老生常谈了,可以直接看这个
1 进程
1.1 进程(Process)
程序本身是指令的有序集合,进程是程序在处理器上的一次执行过程。
程序中包含了创建进程需要的信息。
A program is a file containing a range of information that describes how to construct
a process at run time.
从内核角度来看,process包含user-space中为程序和变量分配的存储,和内核中的一些数据结构。
和进程相关的信息保存在 task_struct
结构体中,这个结构体定义在linux/sched.h
中。
但《The Linux Programming Interface》中没有task的概念,有process,thread的概念,PID指的就是Process ID。除了一些system process,PID和程序没有固定的关系,也就是运行一个程序时创建的进程是不固定的。PID数值是有上限的,可以调整。
Process & Thread:
A process is an instance of an executing program.
A single process can contain multiple threads.
All of these threads are independently executing the same program, and they all share the same global memory, including the initialized data, uninitialized data, and heap segments. (A traditional UNIX process is simply a special case of a multithreaded processes; it is a process that contains just one thread.)
这里还没有具体看进程的属性和生命周期等概念。
1.2 创建进程
1.2.1 理解进程的创建
创建进程对使用者来说有两种方式:
- 在shell中执行命令或可执行文件,其实是由shell进程调用了fork函数创建子进程
- 在自己写的代码中调用fork函数来创建子进程
pstree
命令可以通过一个树的方式,列出系统中的所有进程。可以看到下图中所有的进程都是由init进程创建的(systemd是init进程的一种实现)。init进程即进程1,,其PID固定为1,它是由进程0(PID为0的进程)创建的,进程0由内核创建。进程0在创建进程1后,转换为交换进程或空闲进程。
Linux系统中除了进程0,所有的进程都是由父进程调用fork函数创建的。
1.2.2 fork函数
函数原型为pid_t fork(void)
, 头文件为unistd.h
。
pid_t
就是 unsigned int
。
在程序中,fork();
这条语句之后的程序(包括fork()
这个语句)会以两个进程来运行。之前的不受影响。同时fork 函数在被调用后,在子进程和父进程中的分别返回,返回值不同。 fork函数有三种返回值:
- 子进程中返回值为0 ,提提示当前运行在子进程中
- 父进程中返回值为子进程PID,让父进程掌握所创建子进程的PID
- 出错返回-1
因此可以判断fork函数的返回值,从而在父进程和子进程中执行不同的程序。使用fork函数时,返回值非常重要。
父子进程的异同: