一. 什么是进程:
- 是一个正在执行的程序的实例
- 担当分配系统资源的实体(cpu时间,内存)
- 进程信息被放在一进程控制块的数据结构中,这个进程控制块称为PCB,进程控制块的数据结构叫task_struct
这个task_struct 包括以下几个信息:
- 标识符(pid):描述本进程的唯一标识符,用来区别其他进程(学号)
- 优先级:相对其他信息的优先级
- 程序计数器(eip):程序中即将被执行的下一条指令
- 上下文数据:进程执行时处理器的寄存器中的数据,它保证了进程的自由切换(休学例子)
- 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- i/o状态:包括显示的i/o请求,分配给进程的i/o设备和被进程使用的文件列表
- 记账信息:包括处理器时间总和,使用的时钟数总和,时间限制,记账号等(学生的年纪)
- 状态:任务状态,退出代码,退出信号
·R运行状态
处于这种状态的进程,要么正在运行、要么正准备运行。正在运行的进程就是当前进程(由current所指向的进程),而准备运行的进程只要得到CPU就可以立即投入运行,CPU是这些进程唯一等待的系统资源。系统中有一个运行队列(run_queue),用来容纳所有处于可运行状态的进程,调度程序执行时,从中选择一个进程投入运行。在后面我们讨论进程调度的时候,可以看到运行队列的作用。当前运行进程一直处于该队列中,也就是说,current总是指向运行队列中的某个元素,只是具体指向谁由调度程序决定。
·等待状态
处于该状态的进程正在等待某个事件(event)或某个资源,它肯定位于系统中的某个等待队列(wait_queue)中。Linux中处于等待状态的进程分为两种:可中断的等待状态和不可中断的等待状态。处于可中断等待态的进程可以被信号唤醒,如果收到信号,该进程就从等待状态进入可运行状态,并且加入到运行队列中,等待被调度;而处于不可中断等待态的进程是因为硬件环境不能满足而等待,例如等待特定的系统资源,它任何情况下都不能被打断,只能用特定的方式来唤醒它,例如唤醒函数wake_up()等。
·T停止状态
此时的进程暂时停止运行来接受某种特殊处理。通常当进程接收到SIGSTOP、SIGTSTP、SIGTTIN或 SIGTTOU信号后就处于这种状态。例如,正接受调试的进程就处于这种状态。
·僵死状态
进程虽然已经终止,但由于某种原因,父进程没有读到子进程的退出码(使用wait系统调用),这时子进程就会是一个僵尸进程(子退父不知 ->Z僵尸进程,父退子仍在->孤儿进程 会被1号init进程收养)。僵尸进程会以终止状态保持在进程表中,一直等待父进程读取退出码,即僵尸进程会浪费内存资源 。
解决僵尸进程的方法有:
(1) 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。
(2) 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。
(3) 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
(4)fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。
二。进程和程序的区别:
(1)存储位置不同,程序在硬盘上,进程在内存里
(2)进程除了拥有和程序一样的代码,还有PCB,进程比程序多了很多的数据结构
(3)进程具有动态属性,即为可以有多种状态
(4)程序没有堆栈因为程序被加载到内存中才会分配堆栈
(5)进程的生命周期短暂,程序永久
(6)一个进程只能对应一个程序,而一个程序可以对应多个进程
三。进程和线程的区别:
(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
(2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程。
(3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
(4)线程是轻两级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
(5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
(6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志