操作系统之进程!
操作系统之进程!
月伴飞鱼进程和线程
进程:正在执行的应用程序,线程是轻量级的进程, 进程是分配资源的基础单位。
线程:轻量级进程,是程序执行的基本单位。
线程是进程的一部分,一个线程只能属于一个进程,一个进程可以有多个线程,但至少有一个线程。
每个进程都有独立的代码和数据空间(程序上下文),程序间的切换开销大。
- 每个线程都有自己独立的运行栈和程序计数器(PC),线程间切换开销小。
互斥和同步区别
互斥:
是指在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时。
其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。
同步:
是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行。
这种先后次序依赖于要完成的特定的任务。
孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。
孤儿进程将被init进程所收养,并由init进程对它们完成状态收集工作。
僵尸进程
一个进程使用fork创建子进程,如果子进程退出,而父进程没有调用wait或waitpid获取子进程的状态信息。
那么子进程的进程描述符仍然保存在系统中,这种进程(这个子进程)称之为僵尸进程。
如何清除僵尸进程?
改写父进程,为子进程收尸
具体做法是接收SIGCHLD信号,子进程死后会发送SIGCHLD信号给父进程。
父进程收到此信号后,执行waitpid()函数为其(子进程)进行收尸。
就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,默认处理为忽略,我们可以设置一个函数来对其进行处理。
如果把这个子进程(僵尸进程)的父进程杀掉,僵尸进程会变为孤儿进程,由init进程进行管理,init负责进行清理僵尸进程。
守护进程
守护进程就类似于一个后台进程。
进程状态
创建状态:
- 进程由创建而产生。
就绪状态:
- 进程已经准备好运行的状态,即进程已分配到除CPU以外所有的必要资源后,只要再获得CPU,便可立即执行。
运行状态:
- 进程已经获取CPU,其进程处于正在执行的状态。
阻塞状态:
- 正在执行的进程由于发生某事件(如I/O请求、申请缓冲区失败等)暂时无法继续执行的状态,即进程执行受到阻塞。
终止状态。
进程通信
管道:
写入的数据都是缓存在内核中,另一个进程读取数据时候自然也是从内核中获取,同时通信数据都遵循先进先出原则。
管道这种通信方式效率低,不适合进程间频繁地交换数据。
消息队列:
消息队列不适合比较大数据的传输,因为在内核中每个消息体都有一个最大长度的限制。
消息队列通信过程中,存在用户态与内核态之间的数据拷贝开销。
因为进程写入数据到内核中的消息队列时,会发生从用户态拷贝数据到内核态的过程。
同理另一进程读取内核中的消息数据时,会发生从内核态拷贝数据到用户态的过程。
共享内存:
共享内存的机制,就是拿出一块虚拟地址空间来,映射到相同的物理内存中。
这样这个进程写入的东西,另外一个进程马上就能看到了,都不需要拷贝来拷贝去,传来传去,大大提高了进程间通信的速度。
信号量:
用了共享内存通信方式,带来新的问题,那就是如果多个进程同时修改同一个共享内存,很有可能就冲突了。
- 例如两个进程都同时写一个地址,那先写的那个进程会发现内容被别人覆盖了 。
为了防止多进程竞争共享资源,而造成的数据错乱。
- 所以需要保护机制,使得共享的资源,在任意时刻只能被一个进程访问。
正好,信号量就实现了这一保护机制。
信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。
信号:
信号是进程间通信机制中唯一的异步通信机制,因为可以在任何时候发送信号给某一进程。
Socket:
要想跨网络与不同主机上的进程之间通信,就需要 Socket 通信了。
操作系统执行一个程序的过程
操作系统检测类型是否是可执行文件。
创建进程,并且将可执行文件映射到该进程。
为该进程设置CPU上下文环境。
将代码和数据从磁盘读入内存。
运行过程中发生缺页异常则重复4。