写在前面:之前,我在某大学的算法课上听见老师说,java,是c牺牲了4倍性能的产品,那个时候,我惊讶了,那可是java啊......
一、基础理论
1. 串行程序与并发程序
串行程序: 一个只能被顺序执行的指令列表。
并发程序: 允许其中的串行程序运行在一个或多个可共享CPU之上,同时也允许每个串行程序都运行在专为它服务的CPU上。
2. 并发程序与并行程序
并发程序:可以被同时发起执行的程序。
并行程序:可以在并行的硬件上执行的并发程序。
并发程序代表了所有可以实现真正的或者可能的并发行为的程序。并行程序是并发程序中的一种。
二、多进程编程
1. 进程间通讯IPC(Interprocess Communication)
从处理机制角度看:
IPC分为基于通讯,基于信号,基于同步
基于通讯的IPC方法被分为以数据传送为手段的IPC方法和以共享内存为手段的IPC方法。前者包括了管道(Pipe)和消息队列(Message Queue).管道可以用来传送字节流,而消息队列可以用来传送结构化的消息对象。
基于信号的IPC方法就是我们常说的操作系统的信号(Signal)机制,它是唯一的一种异步IPC方法。在基于同步的IPC方法中,最重要的就是信号灯(Semaphore).
基于同步的IPC方法以共享内存为手段的IPC方法主要以共享内存区(Shared Memory)为代表,它是最快的一种IPC方法。
2. 进程定义
我们通常把一个程序的执行称为一个进程,因为所有的代码都是在进程中执行的。
进程流程:
一个进程可以通过系统调用fork创建若干个新的进程,前者被称为后者的父进程,每个子进程都是源自它的父进程的一个副本。它会获得父进程的数据段、堆和栈的副本,并与父进程共享代码段。每一份副本都是独立的,子进程对属于它的副本的修改对其父进程和兄弟进程都是不可见的。全盘复制父进程的数据是非常低效的。所以内核使用写时复制(Copy On Write, COW)等技术来提高进程创建的效率。当然,刚被创建的子进程也可以通过系统调用exec把一个新的程序加载到自己的内存中,而原来在其内存中的数据段,堆、栈以及代码段就会被替换掉。在这之后,子进程执行的就会是那个刚刚被加载进来的新程序。
进程标识(PID):
- 进程为1的进程就是内核启动进程。
- 进程ID是一个非负整数且总是被顺序的标号,新被创建的进程ID总是前一个被创建的进程ID递增的结果。
- 进程ID也是可以被重复使用的。
- 进程描述符中还会包含当前进程的父进程(PPID)。
进程的状态
- 可运行状态:挂在CPU上运行,时间由进程调度器决定。
- 可中断的睡眠状态:通过响应事件来决定是否执行,(比如网络连接或信号灯)
- 不可中断的睡眠状态:不可中断?
- 暂停状态或跟踪状态:向进程发送SIGSTOP信号就会使该进程转入暂停状态,除非该进程正处于不可中断的睡眠状态。向正处于暂停状态的进程发送SIGCONT信号会使该进程转向可运行状态。处于跟踪状态的进程会暂停并等待跟踪它的进程对他进行操作。跟踪状态与暂停状态非常类似,但是,向处于跟踪状态的进程发送SIGCONT信号并不能是使它恢复。只有当调试进程进行了相应的系统调用或者退出之后,它才能够被恢复
- 僵尸状态:处于此状态的进程即将要结束,该进程占用的绝大多数资源也都已经被回收了,但是考虑到该进程的父进程可能需要其中的一些信息,但是此时的该进程主题已经被删除而只留下了一个空壳,故此状态被称为僵尸状态。
-
退出状态:在这个过程中,有可能连退出码和统计信息都不需要被保留。(当一个进程消亡的时候,内核会给其父进程发送一个SIGCHLD信号以告知此情况。 )
Linux操作心痛进程的状态转换
网友评论