线程与进程的简单比较
2018-03-20 20:32
453 查看
本篇文章主要对线程与进程之间的区别作一简单总结,从内核实现的区别,双方的地址空间、共享的数据、操作原语的比较和多线程与多进程的区别这几方面,做一简单说明。
1、Linux内核线程实现原理
Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。
1. 轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone
2. 从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的
3. 进程可以蜕变成线程
4. 线程可看做寄存器和栈的集合;每一个线程都有自己的函数调用,所以其拥有自己的用户栈空间;内核区也有一个栈空间用来保存寄存器的值(cpu为不同的线程分配时间片,在不同的线程间切换)
需要拥有自己的内核栈空间。
2、进程与线程的地址空间
对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但,页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。
但是,线程不同!两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面。所以两个PCB共享一个地址空间。
实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。如果复制对方的地址空间,那么就产出一个“进程”;如果共享对方的地址空间,就产生一个“线程”。
因此:Linux内核是不区分进程和线程的。只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。
3、为什么说在linux下,线程最是小的执行单位;进程是最小的分配资源单位?
当进程调用pthread_create函数后就蜕变成一个线程,经过多次pthread_create后就有了多个线程,而线程和进程的地位是一样的,当cpu在分配时间轮片时会一视同仁。所以说线程是cpu调度的最小单位;而无论在一个进程中创建多少个线程,它们都共享一个0~4G的内存空间,所以说cpu分配资源是以进程为基本单位的。
4、线程默认共享数据段、代码段等地址空间,常用的是全局变量。而进程不共享全局变量,只能借助mmap。
测试:1、进程之间不共享全局变量
运行结果如下:可以看出,父子进程不共享全局变量
测试线程间共享全局变量,代码如下:
运行结果:线程间共享全局变量
5、进程与线程控制原语对比
6、多线程与多进程的区别
1、Linux内核线程实现原理
Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。
1. 轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone
2. 从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的
3. 进程可以蜕变成线程
4. 线程可看做寄存器和栈的集合;每一个线程都有自己的函数调用,所以其拥有自己的用户栈空间;内核区也有一个栈空间用来保存寄存器的值(cpu为不同的线程分配时间片,在不同的线程间切换)
需要拥有自己的内核栈空间。
2、进程与线程的地址空间
对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但,页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。
但是,线程不同!两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面。所以两个PCB共享一个地址空间。
实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。如果复制对方的地址空间,那么就产出一个“进程”;如果共享对方的地址空间,就产生一个“线程”。
因此:Linux内核是不区分进程和线程的。只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。
3、为什么说在linux下,线程最是小的执行单位;进程是最小的分配资源单位?
当进程调用pthread_create函数后就蜕变成一个线程,经过多次pthread_create后就有了多个线程,而线程和进程的地位是一样的,当cpu在分配时间轮片时会一视同仁。所以说线程是cpu调度的最小单位;而无论在一个进程中创建多少个线程,它们都共享一个0~4G的内存空间,所以说cpu分配资源是以进程为基本单位的。
4、线程默认共享数据段、代码段等地址空间,常用的是全局变量。而进程不共享全局变量,只能借助mmap。
测试:1、进程之间不共享全局变量
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/wait.h> int a = 10; int main() { pid_t pid ,wpid; int status; pid = fork(); if(pid < 0) { perror("fork error!\n"); } else if(pid > 0) //父进程 { a = 20; wpid = wait(&status); if(WIFEXITED(status)) { printf("The child process %d exit normally\n",wpid); printf("return value:%d\n",WEXITSTATUS(status)); } else if(WIFSIGNALED(status)) { printf("The child process exit abnormally, killed by signal %d\n",WTERMSIG(status)); } else { } } else { sleep(2); printf("a = %d\n",a); } return 0; }
运行结果如下:可以看出,父子进程不共享全局变量
➜ test git:(master) ✗ ./a.out fa process wrote a = 20 a = 10 The child process 11937 exit normally return value:0
测试线程间共享全局变量,代码如下:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<pthread.h> int var = 10; void *fun(void *agr) { var = 20; printf("pthread!\n"); return NULL; } int main() { pthread_t tid; int ret; int* retval; printf("before pthread_create: var = %d\n",var); ret = pthread_create(&tid,NULL,fun,NULL); if(ret != 0) { fprintf(stderr,"pthread_create error : %s\n",strerror(ret)); exit(1); } sleep(1); printf("after pthread: var = %d\n",var); pthread_join(tid,(void**)&retval); return 0; }
运行结果:线程间共享全局变量
before pthread_create: var = 10 pthread! after pthread: var = 20
5、进程与线程控制原语对比
进程 | 线程 | 作用 |
---|---|---|
fork() | pthread_create() | 创建 |
exit() | pthread_exit() | 退出 |
wait()/waitpid() | pthread_join() | 回收资源 |
kill() | pthread _cancel() | 杀死进程、线程 |
getpid() | pthread_self() | 获取当前进程/线程号 |
对比维度 | 多进程 | 多线程 | 总结 |
---|---|---|---|
数据共享、同步 | 数据共享复杂,需要IPC;数据是分开的,同步简单 | 因为共享进程数据,数据共享简单,因此,同步复杂 | 各有优势 |
内存、CPU | 占用内存多,切换复杂、CPU利用率低 | 占用内存少,切换简单,CPU利用率高 | 线程占优 |
创建销毁、切换 | 创建销毁、切换复杂,速度慢 | 创建销毁、切换简单,速度快 | 线程占优 |
编程、调试 | 编程简单、调试简单 | 编程复杂、调试复杂 | 进程占优 |
可靠性 | 进程间不会影响 | 一个线程挂掉将会导致整个进程挂掉 | 进程占优 |
分布式 | 适用于多核、多机分布式;扩展机器简单 | 适用于多核分布式 | 进程占优 |
相关文章推荐
- 黄聪:线程,进程和程序的简单比较
- 线程,进程和程序的简单比较
- 线程,进程和程序的简单比较
- [转]线程,进程和程序的简单比较
- linux程序设计之线程、进程和程序的简单比较
- 线程,进程和程序的简单比较
- 任务,线程,进程和程序的简单比较
- 线程,进程和程序的简单比较
- 线程,进程和程序的简单比较
- [转]线程,进程和程序的简单比较
- 【windows--进程和线程】多线程编程(比较完整的简单介绍)
- 线程、进程和程序的简单比较【转】
- 进程与线程的一个简单解释
- 进程与线程的一个简单解释(我看过最好的解释)
- Java 线程与进程的速度比较(继承Thread实现)
- 进程与线程的一个简单解释
- 进程与线程的一个简单解释
- 进程与线程的一个简单解释
- 进程与线程的一个简单解释
- 进程与线程的一个简单解释