冯诺曼体系结构:常见的计算机,如服务器,大部分都遵循冯诺曼体系结构。
任何计算机系统都包含了一个基本的程序集合,称为操作系统。操作系统包括:
OS是一款纯正的“搞管理的软件”;
如何管理:先描述管理对象,再组织管理对象
改图为操作系统内核图片,从图片可以看出,OS下要管理所有的硬件软件资源,上要管理各种软件也要给用户提供一个良好的用户环境。从这可以看出OS就是一款纯正的“搞管理的软件”,如何管理:就是先描述管理的对象,组织管理的对象,以OS如何管理进程为例,深入了解OS如何管理对象组织对象?
/proc
系统文件夹进行查看/proc/1
查看这个文件夹标识符:描述本进程的唯一标识符,用来区别其它的进程。PID就作为某进程的标识符
状态:任务状态,退出代码,退出信号等
优先级:相对于其它的进程的优先级。因为我们大多数的电脑只有一个CPU,而进程有许多个,但是资源是有限的,这样我们就可以来确定优先级的方式使多个进程能够更优的访问资源。
程序计数器:程序中即将被执行的下一条指令地址。程序计数器可以帮助我们执行指令和恢复指令的作用
内存指针:包括程序代码和进程相关数据的指针,还有其他进程共享的内存块。
I/O状态信息:包括显示I/O请求,分配给进程的I/O设备和被进程使用的文件列表
记账信息:可能包括处理器时间总和,使用的时钟总和,时间限制,记账号等。
其他的信息。
上面我们是通过./test
来执行我们的可执行文件来创建进程,而我们也可以用代码来创建子进程。
fork有俩个返回值,如果成功,子进程的PID将在父进程中返回,并且在子进程中返回0。 失败, -1在父进程中返回,没有创建子进程,并且正确设置了errno。
父子进程代码共享,数据各自开辟空间,私有一份
通过下面的代码可以观察父子进程代码共享,而fork()创建成功之后会在父进程返回创建成功子进程的PID。
fork之后通常是要用if进行分流
int main()
4 {
5 int ret = fork();
6 if(ret < 0)
7 {
8 perror("error\n");
9 return 1;
10 }
11 if(ret > 0)
12 {
13 //parent process
14 printf("I am parent process,PID:%d,PPID:%d\n",getpid( ),getppid());
15 }
16 if(ret == 0)
17 {
18 //child process
19 printf("I am child process,PID:%d,PPID:%d\n",getpid() ,getppid());
20 }
21 sleep(1);
22 return 0;
23 }
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
包括:
R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么是在运行队列中。
1 #include <stdio.h>
2 int main()
3 {
4 while(1)
5 {
6 }
7 }
~
S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠)
运行程序:
int main()
3 {
4 while(1)
5 {
6 printf("hello word\n");
E> 7 sleep(1);
8 }
9 }
D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠,在这个状态的进程通常会等待IO的结束
T停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止进程,这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行
X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
僵死状态是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就成为僵尸进程
僵死进程会以终止状态保存在进程表中,并且一直在等待父进程读取状态代码
所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
危害:
进程的退出状态必须维持下去,因为它要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样,如果父进程一直不读取,那么子进程一直处于Z状态。
维护退出状态本身就是要维护数据,也属于进程基本信息,所以保存在PCB中
那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费
内存泄漏
#include
#include
#include
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id == 0){//child
printf("I am child, pid : %d\n", getpid());
sleep(10);
}else{//parent
printf("I am parent, pid: %d\n", getpid());
sleep(3);
exit(0);
}
return 0;
}