1.进程和线程
进程就是处于执行期的程序,进程通常还包括其它资源,像打开的文件,挂起的信号,内核内部数据,处理器状态。
线程机制是现代编程技术中常用的一种抽象概念,该机制提供了在同一程序内共享该内存地址空间运行的一组线程。是在进程中活动的对象。每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。
内核调度的对象是线程,而不是进程。
linux系统的线程实现非常特别:它对进程和线程不特别区分。
在线程之间可以共享虚拟内存,但每个都拥有各自的虚拟处理器。
2.进程的创建
fork()与exec()
首先fork()通过拷贝当前进程创建一个子进程,子进程与父进程的区别仅仅在于PID,PPID和某些资源和统计量。
fork()系统调用从内核返回两次,一次回到父进程,另外一次回到新产生的子进程
exec()函数复制读取可执行文件并将其载入地址空间开始运行。
copy-on-write:Linux的fork()使用写时拷贝页实现。
3.进程的状态
- TASK_RUNNING(运行):进程是可执行的,或者正在执行,或者在运行队列中等待执行。
- TASK_INTERRUPTIBLE(可中断):进程正在睡眠(也就是被阻塞),等待某些条件的达成。
- TASK_UNINTERRUPIBLE(不可中断):除了就算是接收到信号也不会被唤醒或准备投入运行外,这个状态与可打断状态相同。通常在进程必须在等待时不受干扰或等待时间很快就会发生时出现。
- __TASK_TRACED:被其他进程跟踪的进程,例如ptrace调试。
- __TASK_STOPPED:进程停止执行;进程没有投入运行也不能投入运行。通常发生在接收到SIGSTOP,SIGSTP,SIGTIN,SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。
linux中如何看看进程状态? ps -aux ,cat /proc/pid/state 注:pid 为具体进程的pid
3.进程的家族树
系统中的每个进程必有一个父进程,相应的,每个进程也可以拥有零个或多个子进程。进程间的关系存放在进程描述符中。每个task_struct都包含要给只想其父进程task_struct,叫做parent指针,还包含一个称为children的子进程链表。
linux中查看进程家族树?pstree
4.进程的终结
进程的析构是自身引起的,它发生在系统调用exit()系统调用时。
如果父进程在子进程之前退出,就必须有机制来保证子进程找到一个新的父亲,否则这些子进程就会在退出时永远处于贱死状态,白白的消耗内存。