1. 引言
一个程序是存储在文件中的机器指令序列。一般它是由编译器将源代码编译成二进制格式的代码。运行一个程序意味着将这个机器指令序列载入内存然后让处理器(cpu)逐条执行这些指令。
在Unix术语中,一个可执行程序是一个机器指令及其数据的序列。一个进程是程序运行时的内存空间和设置。
数据和程序存储在磁盘文件中,程序在进程中运行。
2. ps
进程存在于用户空间。用户空间是存放运行的程序和它们的数据的一部分内存空间。
使用ps(process status)命令可以查看用户空间的内容。这个命令会列出当前的进程。
用户空间容纳进程
ps
ps -a
ps -l
文件系统容纳文件和目录
ls
ls -a
ls -l
ps
PID TTY TIME CMD
2658 pts/0 00:00:00 bash
2954 pts/0 00:00:00 ps
这个有两个进程在运行:bash(shell)和ps命令。每个进程都有一个可以唯一标识它的数字,被称为进程ID。一般简称为PID。每一个进程都与一个终端相连,这里是/dev/pts/0。每个进程都有一个已运行的时间。注意ps对已运行时间统计并不是非常的精确,从ps只用了0秒就可以看出。
ps -a
ps有很多可选项。和ls命令一样,ps支持-a可选项。-a选项列出所有进程,包括在其他终端由其他用户运行的程序。但是带选项-a的输出并不包括shell。ps也有一个-l选项来打印更多细节:
ps -l
[purple@localhost 0820]$ ps -la
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 R 500 3002 2658 0 80 0 - 1170 - pts/0 00:00:00 ps
名为S的一列表示各个进程的状态。S列的值为R说明ps对应的进程正在运行。如果有其他进程的S列的值为S,说明它们都处于睡眠状态。每个进程都属于相应地UID列指明的用户ID。每个进程都有一个进程ID(PID),同时也有一个父进程ID(PPID)。
标记为PRI和NI的列分别是进程的优先级和niceness级别,内核根据这些值来决定什么时候运行进程。一个进程可以增加niceness级别,这就像在超市排队付账的时候,让其他客户排到自己的前面。超级用户可以减少它的niceness级别,这就像排队的时候插队。
一个进程有大小,这由SZ列表示。这列的数据表示这个进程占用的内存大小。
WCHAN列显示进程睡眠的原因。
ADDR和F已经不在使用,但是为了兼容的原因而保留它们。
ps –fa
[purple@localhost 0820]$ ps -fa
UID PID PPID C STIME TTY TIME CMD
purple 3095 2658 0 20:40 pts/0 00:00:00 ps -fa
-f表示格式化输出,这样便于阅读。用用户名代替UID来显示。在CMD列显示完整的命令行
3. 进程
建立一个进程有点像建立一个磁盘文件。内核要找到一些用来存放程序指令和数据的空闲内存页。内核还要建立数据结构来存放相应的内存分配情况和进程属性。
是操作系统变得神奇的不仅是它的文件系统把一堆旋转圆盘上连续的簇变成有序组织的树状目录结构,并且以相似的机制,它的进程系统将硅片上的一些位组织成一个进程社会。
4. shell
shell是一个管理进程和运行程序的程序。所有常用的shell都有三个主要的功能:
1. 运行程序
grep、date、ls、echo和mail都是一些普通的程序,用c编写,并被编译成机器语言。shell将它们载入内存并运行它们。很多人把shell看成是一个程序启动器(program launcher)。
2. 管理输入和输出
shell不仅仅是运行程序。使用<、>和|符号可以将输入、输出重定向。这样就可以告诉shell将进程的输入和输出连接到一个文件或是其他的进程。
3. 可编程
5. shell如何运行程序
一个shell 的主循环执行下面的4步:
1. 用户键入a.out
2. shell建立一个新的进程来运行这个程序
3. shell将程序从磁盘载入
4. 程序在它的进程中运行直到结束
因此为了要写一个shell,需要学会
1. 运行一个程序
2. 建立一个进程
3. 等待exit()