进程 线程 纤程 :
面试高频:进程和线程有什么区别?(纯理论问题)
答案:(非专业答案)进程就是一个程序运行起来的状态,线程是一个进程中的不同的执行路径。专业:进程是OS分配资源的基本单位,线程是执行调度的基本单位。分配资源最重要的是:独立的内存空间,线程调度执行(线程共享进程的内存空间,没有自己独立的内存空间)
进程:
Linux中也称task,是系统分配资源的基本单位
资源:独立的地址空间,内核数据结构(进程描述符...)全局变量 数据段.....
进程描述符:PCB(Process Control Block)
进程创建与启动:
系统函数:fork() exec()
从A中fork B的话,A称之为B的父进程
僵尸进程:
僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源
我们都知道进程的工作原理。我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
int main() {
pid_t pid = fork();
if (0 == pid) {
printf("child id is %d\n", getpid());
printf("parent id is %d\n", getppid());
} else {
while(1) {}
}
}
孤儿进程:
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
int main() {
pid_t pid = fork();
if (0 == pid) {
printf("child ppid is %d\n", getppid());
sleep(10);
printf("parent ppid is %d\n", getppid());
} else {
printf("parent id is %d\n", getpid());
sleep(5);
exit(0);
}
}
进程(任务)调度:
内核任务调度器决定 :该哪一个进程运行?何时开始?运行多长时间?
在Linux内核中有许多的调度方案
线程:
线程在Linux中的实现:
就是一个普通的进程,只不过和其他进程共享资源(内存空间 全局数据等)其他系统都有各自的所谓的LWP实现Light Weight Process
高层面理解:一个进程中不同的执行路线
纤程:用户态的线程,线程中的线程,切换和调度不需要经过OS
优势:1:占有资源很少 OS : 启动一个线程大概1M空间 Fiber:启动一个纤程大概4K空间 2:切换比较简单(切换不需要经过操作系统) 3:可以启动很多个纤程(10W+)
目前支持内置纤程的语言:Kotlin Scala Go Python(lib)... Java(通过类库是可以支持的)jdk14现在不支持
纤程的应用场景:很短的计算任务,不需要和内核打交道,并发量高!
额外知识:go语言比Java语言先进,先进在哪里?其实就是go语言自带了纤程,而Java没有实现(这是核心点)