以下本文都是在OS角度說的。
面試高頻:進(jìn)程和線程有什么區(qū)別?
非專業(yè)回答:進(jìn)程就是一個(gè)程序運(yùn)行起來的狀態(tài),線程是一個(gè)進(jìn)程中的不同的執(zhí)行路徑
專業(yè)回答:進(jìn)程是OS分配資源的基本單位,線程是執(zhí)行調(diào)度的基本單位
分配資源最重要的是:獨(dú)立的內(nèi)存空間,線程調(diào)度執(zhí)行(線程共享進(jìn)程的內(nèi)存空間,沒有自己獨(dú)立的內(nèi)存空間)纖程:用戶態(tài)的線程,線程中的線程,切換和調(diào)度不需要經(jīng)過OS
優(yōu)勢(shì):1:占有資源很少 OS : 線程1M Fiber:4K 2:切換比較簡單 3:啟動(dòng)很多個(gè)10W+
截止本文發(fā)布時(shí)支持內(nèi)置纖程的語言:Kotlin Scala Go Python(lib)... Java? (open jdk : loom)
JAVA中對(duì)纖程的支持:目前沒內(nèi)置,期望內(nèi)置
利用Quaser庫(不成熟)
<dependencies>
<dependency>
<groupId>co.paralleluniverse</groupId>
<artifactId>quasar-core</artifactId>
<version>0.8.0</version>
</dependency>
</dependencies>
// 線程版本:
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.SuspendableRunnable;
public class HelloFiber {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
Runnable r = new Runnable() {
@Override
public void run() {
calc();
}
};
int size = 10000;
Thread[] threads = new Thread[size];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(r);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
static void calc() {
int result = 0;
for (int m = 0; m < 10000; m++) {
for (int i = 0; i < 200; i++) result += i;
}
}
}
// 大概耗時(shí)7s
// 纖程版本
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.SuspendableRunnable;
public class HelloFiber2 {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
int size = 10000;
Fiber<Void>[] fibers = new Fiber[size];
for (int i = 0; i < fibers.length; i++) {
fibers[i] = new Fiber<Void>(new SuspendableRunnable() {
public void run() throws SuspendExecution, InterruptedException {
calc();
}
});
}
for (int i = 0; i < fibers.length; i++) {
fibers[i].start();
}
for (int i = 0; i < fibers.length; i++) {
fibers[i].join();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
static void calc() {
int result = 0;
for (int m = 0; m < 10000; m++) {
for (int i = 0; i < 200; i++) result += i;
}
}
}
// 大概耗時(shí)3秒,纖程之間的切換很輕盈,是在用戶態(tài)內(nèi)部進(jìn)行的,不需要os參與
大家可以嘗試:目前是10000個(gè)Fiber -> 1個(gè)JVM線程,想辦法提高效率,10000Fiber -> 10份 -> 10Threads
纖程的使用的場(chǎng)景
纖程 vs 線程池:很短的計(jì)算任務(wù),不需要和內(nèi)核打交道,并發(fā)量高!
進(jìn)程創(chuàng)建和啟動(dòng)

linux是c語言寫的,它對(duì)外提供一些類庫和接口,比如fork(),創(chuàng)建進(jìn)程調(diào)用系統(tǒng)的函數(shù)fork() 產(chǎn)生一個(gè)子進(jìn)程,其實(shí)內(nèi)部還是clone方式產(chǎn)生的,即從父進(jìn)程克隆出一個(gè)
僵尸進(jìn)程 & 孤兒進(jìn)程
- 僵尸進(jìn)程:父進(jìn)程產(chǎn)生子進(jìn)程之后,會(huì)維護(hù)子進(jìn)程的一個(gè)PCB結(jié)構(gòu),如果子進(jìn)程退出了,由父進(jìn)程釋放;如果父進(jìn)程沒有釋放,那么子進(jìn)程成為一個(gè)僵尸進(jìn)程。
- 孤兒進(jìn)程:子進(jìn)程結(jié)束之前,父進(jìn)程已經(jīng)退出
孤兒進(jìn)程會(huì)成為init進(jìn)程的孩子,由1號(hào)進(jìn)程維護(hù)
進(jìn)程調(diào)度(了解)
Linux 2.6采用CFS調(diào)度策略:Completely Fair Scheduler
按優(yōu)先級(jí)分配時(shí)間片的比例,記錄每個(gè)進(jìn)程的執(zhí)行時(shí)間,,如果有一個(gè)進(jìn)程執(zhí)行時(shí)間不到他應(yīng)該分配的比例,優(yōu)先執(zhí)行。
默認(rèn)調(diào)度策略:
實(shí)時(shí)優(yōu)先級(jí)分高低 : FIFO (First In First Out),
優(yōu)先級(jí)一樣 : RR(Round Robin)
普通: CFS
- 多任務(wù)
-- 非搶占式:除非進(jìn)程主動(dòng)讓出cpu,否則一直運(yùn)行
-- 搶占式:由進(jìn)程調(diào)度器強(qiáng)制開啟或暫停某一進(jìn)城的執(zhí)行
————————————————————
坐標(biāo)帝都,白天上班族,晚上是知識(shí)的分享者
如果讀完覺得有收獲的話,歡迎點(diǎn)贊加關(guān)注