linux多进程与多线程。
一,线程与进程的对应关系
先回答一个大家比较关心的问题,就是线程和进程的对应关系。
第一点:一个进程可以有多个线程。
第二点:一个线程只能属于一个进程。也就是说一个线程不能对应多个进程。
二,linux父进程与子进程
子进程只是一个额外的流程,那他跟父进程的联系和区别是什么呢?
我很想建议你看看linux内核的注解(有兴趣可以看看,那里才有本质上的了解),总之,fork后,子进程会复制父进程的task_struct结构,并为子进程的堆栈分配物理页。理论上来说,子进程应该完整地复制父进程的堆,栈以及数据空间,但是2者共享正文段。
关于写时复制:由于一般 fork后面都接着exec,所以,现在的 fork都在用写时复制的技术,顾名思意,就是,数据段,堆,栈,一开始并不复制,由父,子进程共享,并将这些内存设置为只读。直到父,子进程一方尝试写 这些区域,则内核才为需要修改的那片内存拷贝副本。这样做可以提高 fork的效率。
需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。
消耗资源:
从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。
通讯方式:
进程之间传递数据只能是通过通讯的方式,即费时又不方便。线程时间数据大部分共享(线程函数内部不共享),快捷方便。但是数据同步需要锁对于static变量尤其注意
线程自身优势:
提高应用程序响应;使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上;
改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
三,父进程与子进程共享哪些数据
注意:父子进程之间遵循读时共享,写时复制的原则。也就是Copy On Write。
1,父子进程共享的数据。
全局变量。
.data。
.text。
栈。
堆。
环境变量。
用户ID。
宿主目录。
进程工作目录。
信号处理方式。
2,父子进程非共享的数据。
进程ID。
父进程ID。
fork返回值。
进程运行时间。
闹钟(定时器)。
未决信号集。
四,linux的Copy On Write机制
有个疑问:子进程是有pid吗?
答:有。
也就是说,子进程是操作系统级别的进程吗?
答:是。
子进程和父进程地位相同吗?
答:都属于操作系统级别的进程。
一个线程只能属于一个进程,但是一个进程程可以创建多个子进程?
答:是的。
单线程的redis,是不是只能对应一个操作系统的进程?
答:不是的。redis同事处理多个请求其实就是利用了操作系统的Copy On Write多进程机制。
网友评论