进程和线程的区别是很常见的面试题,网上虽然随意就可以百度到,但是大多都是直接从理论上进行解释,很少有从操作系统的实现方面进行解释,笔者此篇以linux系统为例,做一个进程和线程笔记。
一般概念
进程:
是操作系统分配和管理资源的最基本单位。
线程:
是进程中的单一顺序流。
两者设计初衷
进程:
提高了CPU的使用效率。
比如打印机打印东西的同时还可以打游戏,因为打游戏和打印机是两个不同的并发进程。
线程:
线程之间资源共享,减少了IPC资源的消耗。
linux中的实现
在linux中,线程只是一种特殊的进程。线程和进程的唯一区别就是线程间资源共享,而进程间资源独立。
进程线程创建代码比较
众所周知,在linux中是通过fork()进行进程的创建的,而fork()本身是由clone()实现的。
fork()的实现为:
clone(SIGCHLD,0);
而线程创建的clone代码如下:
clone(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND,0);
clone参数的对应作用如下:
CLONE_VM:父子进程共享地址空间
CLONE_FS:父子进程共享文件系统信息
CLONE_FILES:父子进程共享打开的文件
CLONE_SIGHAND:父子进程共享信号处理函数及被阻断的信号
可以看到,进程和线程创建的唯一区别就是线程共享了父子进程之间的各种资源,如此操作,那么创建出的父进程和被创建出的子进程就是我们通常意义上所讲的线程。
进程描述符上的表现
linux内核把进程的所有信息以双向链表的形式存储在任务队列中。其中的每一个节点便称作进程描述符,每一个进程描述符包含一个进程的所有信息。(比如PID,进程状态等)
一般的进程
一个进程必然只对应着一个进程描述符。
同一个进程中的多个线程
这些线程所以对应的是同一个进程描述符。
通过同一个进程中多个线程指向同一个进程描述符,实现了线程间的资源共享。