Linux下进程线程区别
定义
- 对于有线程系统:
- 进程是资源分配的独立单位
- 线程是资源调度的独立单位
- 对于无线程系统:
- 进程是资源调度、分配的独立单位
创建
- 进程和线程的创建都是通过clone(2)来实现的
- fork()->clone(SIGCHLD,0)
- pthread_create()->clone(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND,0)
- vfork()->clone(CLONE_VFORK|CLONE_VM|SIGCHLD,0)
SIGCHLD 意思是要求在子进程创建时必须注册SIGCHLD信号。当子进程退出时,系统会给父进程发送SIGCHLD信号,对其进行处理,避免子进程变成僵尸进程
CLONE_VFORK 使子进程创建以后优先于父进程运行(父进程此时被阻塞睡眠),直到子进程终结(terminate)或发出一个fatal信号或调用execve
线程共享虚拟地址空间,文件系统信息,打开的文件,信号处理函数和被阻断的信号
Linux进程创建三——fork、vfork、clone、kernel_thread
共享的资源
- 进程
- 私有
- 地址空间,全局变量,堆,栈,寄存器
- 共享
- 内核空间
- 代码段被共享(关于共享库的知识)how is a shared library file called by two different processes in Linux?
- 进程目录(父子进程)
- 公共数据(共享内存办法:mmap等)
- 私有
- 线程
- 私有
- 线程栈,寄存器
- 共享
- 地址空间,堆,全局变量,静态变量
- 私有
进程栈和线程栈
- 进程栈
- 虚拟地址空间当中user space 的stack区
- 线程栈
- 从进程的地址空间当中map出来的一块区域,大小固定,不支持动态增长
- 是同一个进程的所有线程生成的时候浅拷贝生成者的 task_struct 的很多字段,其中包括所有的 vma,如果愿意,其它线程也还是可以访问到的,于是一定要注意。
Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈
上下文切换
- 进程上下文切换:
- CPU上下文切换(系统调用是发生的就是CPU上下文切换)
- 内核栈信息
- 虚拟内存替换(还有TLB刷新)、栈、全局变量等用户空间资源
- 线程上下文切换
进程组和线程组
- 进程组
- 是用来方便管理进程的,一个进程只能属于一个进程组,只要进程组当中的一个进程没有结束,那么整个进程也没有结束
- 线程组
- 对线程getpid得到的并不是线程本身的pid,而是tgid
- 一个tgid就是一个线程组
通信
-
进程通信
- 管道(pipe),流管道(s_pipe)和有名管道(FIFO)
- 信号(signal)
- 消息队列
- 共享内存(mmap等)
- 信号量
- 套接字(socket)
-
线程同步/通信:线程的通信主要是为了线程之间的同步,所以没有复杂的数据交换通信机制
- 锁机制
- 互斥锁+条件变量
- 读写锁
- 信号量机制
- 信号机制
- 锁机制
数据安全 (并发上)
- 进程同步
- 共享内存上加互斥锁和条件变量
- 读写锁,记录锁,信号量,屏障
- 线程同步
- 互斥量,条件变量,自旋锁,屏障,信号量,读写锁
- 区别在于锁的数据的位置,放在一个进程内的数据,还是数据
终止
- windows中方法上: 分析进程、线程的终止
- Linux中,终止的细节:
待补充…
多线程和多进程的选择
- 多进程
- 优点:编程、调试简单,可靠性较高
- 缺点:创建、销毁、切换速度慢,内存、资源占用大
- 多线程
- 创建、销毁、切换速度快,内存、资源占用小
- 缺点:编程、调试复杂,可靠性较差
- 选择
- 要频繁创建销毁or 大量计算:线程
- 强相关:线程,弱相关:进程
- 可能要扩展到多机分布的用进程,多核分布的用线程
多线程还是多进程的选择及区别