#技术笔记
1.从用户视角来看,进程是一个运行起来的程序,如果只是安装了程序,这样不叫进程,只有这些东西运行起来才算进程。
2.虚拟内存:我们认为我们占用的内存,是从0开始一块连续的内存。虚拟内存到真实内存,操作系统在底层做映射。直接使用物理内存的话,进程间隔离困难,内存碎片,程序员管理内存麻烦。
3.虚拟CPU:我们认为,我们的程序在运行的时候就是一个程序独占CPU。
4.进程的调度:谁抢到CPU 谁就执行。CPU是把时间划分成一个个时间片的,要使用,就来抢。
5.进程需要自己保存信息:内存,PCB(进程控制块),在Linux 是用结构体保存自己的信息。
- ps命令
ps 命令常用的两种形式就是, ps -elf 和 ps aux。某些列字段的含义,PID 是进程id,用来唯一标识进程;PPID 是父进程id;CMD 启动进程的命令。
- free命令
free 的作用就是显示内存的使用情况, 使用时最好用 free -h <----- 这里的-h是人类阅读模式。某些列字段含义,buff/cache 缓冲区和页缓冲占用的内存大小。Swap 是交换区, 将不常用的内存数据临时移到磁盘上,这块磁盘空间就叫swap。
- top命令
显示用户数、任务数、电脑启动时间等;其中load average : 0.00,0.00,0.00 这3个数分别表示1/5/15分钟平均负载,如果 第一个数特别大,其他后面两个小一点,说明近期CPU在被激烈竞争,有可能是系统启动,或者一些攻击行为,或者定时任务启动等等。更具体查看可以使用htop命令,使用的时候安装一下即可。
9.kill命令
通常用于终止进程, kill -2 PID 和 kill -9 PID,第一个是让进程自己挂,第二个是强制终止。
10.fork()
fork 就是用来**创建子进程。**fork 之前的代码有一个进程在执行,fork之后的代码有两个进程执行。
下面有些许绕,fork 的返回值(假设是 ret),如果 ret 是0,则表示现在在新进程(且新进程pid 大概是父进程的 pid + 1),如果 ret 非0,则表明在父进程,ret 的值是子进程的pid,如果是-1,代表创建进程失败。例如如下代码。
#include <my_headerc.h>
int main(int argc, char *argv[])
{
printf("pid = %d\n", getpid());
pid_t ret = fork();
if(ret == 0)
{
printf("child, pid = %d, ppid = %d, ret = %d\n", getpid(), getppid(), ret);
}
else
{
printf("father, pid = %d,ppid = %d, ret = %d\n", getpid(), getppid() , ret);
}
return 0;
}
运行结果是:
pid = 39872
father, pid = 39872,ppid = 37086, ret = 39873
child, pid = 39873, ppid = 39872, ret = 0
一般来说都是父进程先运行完。
fork有个机制是写时复制(COW, copy on write),由于每次要是复制一整个内存,开销就太大了,所以采用写时复制,复制的单位是页,并不是整个物理内存。
12.exec 函数族
使用 execl,execv 都可以在当前进程,调用其他进程。 第一个excel 参数是一个一个给,第二个是给一个数组。
- shell 的本质就是创建进程, 让新进程干新活,老进程干老活; 用 fork + exec 可以实现。