五个基本问题
Q1:什么是程序,什么是进程,区别在哪里?
程序:程序是描述在运行时如何创建一个进程。
程序是存储在硬盘的可执行文件,其用来描述创建进程的相关信息。
进程:进程是正在运行的程序实例。
进程是运行的程序,其包含两个部分:处于用户空间的程序代码及变量与处于内核空间的进程状态信息(进程控制块)。
Q2:如何查看系统中有哪些进程?
一、ps指令
显示全部进程
ps -aux
显示部分进程
grep(文件查找)
例:
ps -aux|grep init//显示关于init的进程
二、top指令(类似win里的任务管理器)(可用于评估程序)
Q3:什么是进程标识符(pid)和父进程标识符(ppid)?
PID和PPID:
1、PID(process ID):
与前面的文件标识符fd类似
PID是程序被操作系统加载到内存成为进程后动态分配的资源。
每次程序执行的时候,操作系统都会重新加载,PID在每次加载的时候都是不同的。
Pid=0:称为交换进程(swapper),作用—进程调度(例:网络、内存等资源调度)
Pid=1: init进程,作用—系统初始化(例:开机界面)
2、PPID(parent process ID):PPID是程序的父进程号。
3、PID和PPID都是非零的整数。
4、PID是唯一的,一个PID只标识一个进程。
5、一个进程创建的另一个新进程称为子进程。相反地,创建子进程的进程称为父进程。
6、对于一个普通的用户进程,它的父进程就是执行它的哪个Shell,对于Linux而言,Shell就是bash。
获取当前进程的pid和ppid的API:getpid()
需要包含两个头文件
#include <sys/types.h>
#include <unistd.h>
函数名
pid_t getpid(void);
pid_t getppid(void);
返回值
当前进程pid、ppid
例
int main()
{
pid_t pid;
pid_t ppid;
pid = getpid();
ppid = getppid();
printf("pid = %d\n",pid);
printf("ppid = %d\n",ppid);
while(1){
}
return 0;
}
Q4:什么是父进程,什么叫子进程?
进程A创建了进程B,那么A叫做父进程,B叫做子进程,父子进程是相对的概念,理解为人类中的父子关系
Q5:C程序的存储空间是如何分配?
由高地址往低地址向下依次是:
栈:
自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次调用函数时,其返回地址以及调用者的环境信息(例如某些机器寄存器的值)都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。
通过以这种方式使用栈,可以递归调用C函数。递归函数每次调用白身时,就使用一个新的栈帧,因此一个函数调用实例中的变量集不会影响另一个函数调用实例中的变量。
堆:
通常在堆中进行动态存储分配。由于历史上形成的惯例,堆位于非初始化数据段和栈之间。
未初始化数据段:
通常将此段称为bss段,这一名称来源于一个早期的汇编运算符,意思是“block started by symbol”(由符号开始的块),在程序开始执行之前,内核将此段中的数据初始化为0或空指针。出现在任何函数外的C声明
long sum[1000];
使此变量存放在非初始化数据段中。
初始化数据段:
通常将此段称为数据段,它包含了程序中需明确地赋初值的变量。例如,C程序中出现在任何函数之外的声明:
int maxcount - 99;
使此变量带有其初值存放在初始化数据段中。
正文段:
这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是频繁执行的程序(如文本编辑器、C编译器和shell等)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外而修改其自身的指令。