知名b2b網(wǎng)站怎么給自己的網(wǎng)站設(shè)置關(guān)鍵詞
文章目錄
- 1.先談?dòng)布?/li>
- 馮諾依曼體系結(jié)構(gòu)
- 2.再談軟件
- 操作系統(tǒng)
- 什么是操作系統(tǒng)?
- 為什么要有操作系統(tǒng)?
- 如何管理?
- 系統(tǒng)調(diào)用
- 3.再談進(jìn)程
- 那么具體Linux是怎么做的?
- 指令 ps ajx 查看所有進(jìn)程 非實(shí)時(shí)
- top 實(shí)時(shí)查看進(jìn)程 相當(dāng)于任務(wù)管理器
- ls /proc 內(nèi)存級(jí)進(jìn)程可視化.,系統(tǒng)中動(dòng)態(tài)運(yùn)行的進(jìn)程信息
- 后續(xù)要學(xué)習(xí)tast_struct結(jié)構(gòu)體內(nèi)描述進(jìn)程的各種屬性
- 創(chuàng)建進(jìn)程的方法
- fork()創(chuàng)建子進(jìn)程
- 執(zhí)行流
- 問題
- 問題二
- 進(jìn)程狀態(tài)
- 1.介紹操作系統(tǒng)學(xué)科 中 進(jìn)程狀態(tài),運(yùn)行,阻塞,掛起
- 運(yùn)行態(tài)
- 阻塞狀態(tài)
- 掛起
- 2.具體Linux狀態(tài)如何維護(hù)的?
- R 運(yùn)行態(tài)
- S狀態(tài) 阻塞態(tài) 淺度睡眠(可被喚醒)
- D狀態(tài) 深度睡眠 不響應(yīng)任何請(qǐng)求 阻塞態(tài)
- T && t
- X(dead)
- Z(zombie)
- 孤兒進(jìn)程
- linux中對(duì)應(yīng)掛起狀態(tài)
- Linux中tast_struct(pcb)結(jié)構(gòu)體對(duì)象組織交叉
- 進(jìn)程優(yōu)先級(jí)
- 操作系統(tǒng)是如何根據(jù)優(yōu)先級(jí),開展的調(diào)度呢???
- 位圖
- Linux內(nèi)核的O(1)調(diào)度算法!
1.先談?dòng)布?/h1>
馮諾依曼體系結(jié)構(gòu)
除了Cpu和內(nèi)存,其他都是外設(shè)
除了Cpu和內(nèi)存,其他都是外設(shè)
一個(gè)計(jì)算機(jī)能夠正常運(yùn)行,就必須遵守馮諾依曼體系
數(shù)據(jù)流向
為什么不把Cpu直接懟到輸入設(shè)備和輸出設(shè)備中間,非要加個(gè)內(nèi)存呢?
答:因?yàn)楦鶕?jù)木桶原理,如果這樣設(shè)計(jì),導(dǎo)致最終效率會(huì)由外設(shè)的效率為主,而外設(shè)非常慢。
并且Cpu 的存儲(chǔ)空間非常小,就注定了外設(shè)會(huì)拖慢cpu
那么按照馮諾依曼體系結(jié)構(gòu),這種依然串行的結(jié)構(gòu),輸入設(shè)備把數(shù)據(jù)拷到內(nèi)存,內(nèi)存在拷到cpu,輸出同理,好像也沒快多少?
是的,但是可以把數(shù)據(jù)從輸入設(shè)備預(yù)加載到內(nèi)存之中,并且在加載過程中cpu同時(shí)處理別的事情,接下來cpu就只和內(nèi)存進(jìn)行交互,也就是說cpu的加載和計(jì)算可以同時(shí)進(jìn)行,我們就由串行變成并行,經(jīng)過這樣的運(yùn)行調(diào)度,所以各個(gè)硬件就可以并行跑起來,所以效率提高了。
這個(gè)調(diào)度是誰做的?操作系統(tǒng)
一個(gè)程序要運(yùn)行,必須先加載到內(nèi)存中運(yùn)行?為什么?
因?yàn)轳T諾依曼體系結(jié)構(gòu)規(guī)定!
你的代碼和數(shù)據(jù)要讓cpu運(yùn)行,而cpu只從內(nèi)存中拿數(shù)據(jù),而程序是在外設(shè)磁盤上,就注定要把程序先加載到內(nèi)存
為什么我們當(dāng)時(shí)寫的進(jìn)度條,默認(rèn)顯示的數(shù)據(jù),是可能會(huì)緩存起來的?
在哪里緩存?
按照正常數(shù)據(jù)流向,數(shù)據(jù)換成到內(nèi)存中的某個(gè)區(qū)域,只不過沒有刷新它
2.再談軟件
操作系統(tǒng)
什么是操作系統(tǒng)?
為什么要有操作系統(tǒng)?
對(duì)下管理好軟硬件資源
對(duì)上提供良好的運(yùn)行環(huán)境
如何管理?
管理 建模
所有的計(jì)算機(jī)世界,軟件,代碼都遵循 先描述再組織
拿數(shù)據(jù)是通過執(zhí)行者,也就是驅(qū)動(dòng)程序,拿到軟硬件相關(guān)數(shù)據(jù)
在操作系統(tǒng)內(nèi)部要對(duì)被管理對(duì)象進(jìn)行建模,形成對(duì)應(yīng)的某種數(shù)據(jù)結(jié)構(gòu),所以對(duì)軟硬件資源的管理轉(zhuǎn)換成對(duì)某種數(shù)據(jù)結(jié)構(gòu)的增刪查改
之前在學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)queue時(shí),對(duì)于把頭尾結(jié)點(diǎn)指針用結(jié)構(gòu)體包起來的操作不是很懂,那現(xiàn)在學(xué)過先描述再組織,就很好理解了,就是用結(jié)構(gòu)體來描述隊(duì)列的屬性(隊(duì)頭,隊(duì)尾),再利用鏈表增刪改查進(jìn)行組織。
學(xué)習(xí)C/C++在告訴我們?nèi)绾蚊枋?#xff0c;學(xué)數(shù)據(jù)結(jié)構(gòu)是為了學(xué)習(xí)如何組織。
系統(tǒng)調(diào)用
用戶能不能繞過操作系統(tǒng)直接訪問硬件?
答:不能,你不會(huì),你不懂硬件
語言在變,操作系統(tǒng)的思想是不變的
任何語言要進(jìn)行訪問硬件,必須經(jīng)過操作系統(tǒng),他要經(jīng)過操作系統(tǒng)就必須得系統(tǒng)調(diào)用
3.再談進(jìn)程
左手計(jì)算機(jī)體系層狀結(jié)構(gòu)系統(tǒng)調(diào)用的概念,右手操作系統(tǒng)管理的核心思路
7-28 15min:46
利用屬性來構(gòu)建pcb結(jié)構(gòu)體對(duì)象,對(duì)象中充滿了描述進(jìn)程的屬性
單獨(dú)PCB不叫進(jìn)程
因?yàn)橐粋€(gè)程序要運(yùn)行,就必須將它的代碼和數(shù)據(jù)加載的內(nèi)存之中
單獨(dú)代碼和數(shù)據(jù)也不叫進(jìn)程,它就像教務(wù)系統(tǒng)里面沒有保安的信息
pcb + 代碼數(shù)據(jù)才叫進(jìn)程
對(duì)進(jìn)程進(jìn)行管理,一個(gè)進(jìn)程要進(jìn)入運(yùn)行隊(duì)列或者阻塞隊(duì)列是進(jìn)程的PCB在排隊(duì),而不是它的代碼和數(shù)據(jù)在排隊(duì)
那么具體Linux是怎么做的?
pcb -> task_struct結(jié)構(gòu)體,里面包含進(jìn)程的所有屬性
Linux中如何組織進(jìn)程,Linux內(nèi)核中,最基本的組織進(jìn)程task_struct的方式,采用雙向鏈表組織的
指令 ps ajx 查看所有進(jìn)程 非實(shí)時(shí)
top 實(shí)時(shí)查看進(jìn)程 相當(dāng)于任務(wù)管理器
ls /proc 內(nèi)存級(jí)進(jìn)程可視化.,系統(tǒng)中動(dòng)態(tài)運(yùn)行的進(jìn)程信息
后續(xù)要學(xué)習(xí)tast_struct結(jié)構(gòu)體內(nèi)描述進(jìn)程的各種屬性
-
pid
唯一標(biāo)識(shí)符操作系統(tǒng)為了管理這兩個(gè)進(jìn)程要?jiǎng)?chuàng)建2個(gè)不同的pcb結(jié)構(gòu)體
-
程序計(jì)數(shù)器(pc指針),eip
-
cwd 當(dāng)前工作目錄
為什么touch test.c 我們沒給在哪里創(chuàng)建,當(dāng)touch變成進(jìn)程時(shí),他怎么知道是在哪里創(chuàng)建呢?
因?yàn)閠ouch進(jìn)程啟動(dòng)時(shí),有自己的當(dāng)前工作目錄,所以可以不用帶路徑
-
exe->指向的是二進(jìn)制可執(zhí)行程序所在目錄
創(chuàng)建進(jìn)程的方法
- ./運(yùn)行我們的程序—指令級(jí)別
- fork() ----代碼層面創(chuàng)建的子進(jìn)程
fork()創(chuàng)建子進(jìn)程
代碼
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main()
{printf("begin: 我是一個(gè)進(jìn)程,pid:%d,ppid:%d\n",getpid(),getppid());pid_t id = fork();if(id == 0){//子進(jìn)程while(1){printf("我是子進(jìn)程,pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}}else if(id > 0){//父進(jìn)程while(1){printf("我是父進(jìn)程,pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}}else {//出錯(cuò)}// while(1)// {// printf("hello bit,my pid is:%d my ppid is %d\n",getpid(),getppid());// sleep(1);// }return 0;
}
getpid,getppid是系統(tǒng)調(diào)用接口,其實(shí)就是C語言寫的函數(shù)
用來獲取pid和父進(jìn)程的pid
執(zhí)行流
fork創(chuàng)建了新的子進(jìn)程,變成了2個(gè)執(zhí)行流
問題
1.為什么fork要給父進(jìn)程返回子進(jìn)程pid,給子進(jìn)程返回0?
fork函數(shù)是干什么的?它做了什么?
fork()也是一個(gè)函數(shù)
2.一個(gè)函數(shù)是如何做到返回兩次的?如何理解?
return ret是代碼,父子共享,到達(dá)return時(shí)創(chuàng)建子進(jìn)程的工作早就做完了,子進(jìn)程允許被cpu調(diào)度了,所以return時(shí)就返回了2次,父進(jìn)程1次,子進(jìn)程1次
- 為什么id具有不同的值,既等于0,又>0?
父進(jìn)程是帶資進(jìn)組的,上來就有代碼和數(shù)據(jù),但是子進(jìn)程是沒有代碼和數(shù)據(jù)的,所以只能子進(jìn)程共享父進(jìn)程的代碼。
父進(jìn)程有它自己的數(shù)據(jù),子進(jìn)程必須也要有數(shù)據(jù),根據(jù)進(jìn)程在運(yùn)行時(shí),具有獨(dú)立性,所以絕對(duì)不能父子訪問同樣的數(shù)據(jù)!
父子進(jìn)程對(duì)同一份代碼進(jìn)行讀取,他們互不影響,而代碼在運(yùn)行時(shí)無法修改,只能修改數(shù)據(jù)。
共享代碼并不影響?yīng)毩⑿?br /> 所以子進(jìn)程要把數(shù)據(jù)單獨(dú)拷貝一份,而且沒必要完全拷貝父進(jìn)程的所有數(shù)據(jù),子進(jìn)程有可能根本不會(huì)訪問父進(jìn)程的任意一個(gè)數(shù)據(jù)(通篇拷貝有效率負(fù)擔(dān))。操作系統(tǒng)識(shí)別:當(dāng)子進(jìn)程嘗試去修改父進(jìn)程的數(shù)據(jù)時(shí),才會(huì)拷貝一份新的數(shù)據(jù),子進(jìn)程用多少,給你申請(qǐng)多少,這種技術(shù)稱為:數(shù)據(jù)層面的寫時(shí)拷貝! 這樣父子進(jìn)程就不會(huì)互相影響。
id是父進(jìn)程的數(shù)據(jù),return的時(shí)候是寫入
那么必定發(fā)生寫時(shí)拷貝,所以子進(jìn)程訪問的是拷貝出來的新數(shù)據(jù),父進(jìn)程訪問的是老數(shù)據(jù)
所以他們兩個(gè)看起來是同一個(gè)id,但實(shí)際上訪問的是不同的內(nèi)存
但我還是不懂為什么同一個(gè)變量名是如何做到讓父子進(jìn)程看到不同的內(nèi)容呢?
地址空間再說
問題二
調(diào)度器盡可能做到公平調(diào)度
bash(王婆) 為了不砸自己招牌,創(chuàng)建了子進(jìn)程,這樣子進(jìn)程崩了就不會(huì)影響B(tài)ash
bash如何創(chuàng)建子進(jìn)程呢?
答:fork()
進(jìn)程狀態(tài)
1.介紹操作系統(tǒng)學(xué)科 中 進(jìn)程狀態(tài),運(yùn)行,阻塞,掛起
運(yùn)行態(tài)
一個(gè)Cpu綁定一個(gè)運(yùn)行隊(duì)列,4個(gè)cpu有4個(gè)運(yùn)行隊(duì)列
運(yùn)行隊(duì)列
只要在運(yùn)行隊(duì)列里就叫運(yùn)行態(tài)(R)
調(diào)度器(函數(shù))把struct runqueue當(dāng)作參數(shù)傳入調(diào)度器,調(diào)度器就可以看到所有運(yùn)行隊(duì)列上的PCB
2.一個(gè)進(jìn)程只要把自己放到CPU上開始運(yùn)行了,是不是一直要執(zhí)行完畢,才把自己放下來?
每個(gè)進(jìn)程都有一個(gè)時(shí)間片概念,每個(gè)進(jìn)程在cpu最多跑個(gè)10ms,就被扒下來,繼續(xù)排隊(duì)
在一個(gè)時(shí)間段內(nèi),所有的進(jìn)程代碼都會(huì)被執(zhí)行! 并發(fā)執(zhí)行
大量的把進(jìn)程從CPU上放上去,拿下來的動(dòng)作–進(jìn)程切換
不要拿自己的感受來衡量cpu,cpu對(duì)運(yùn)行隊(duì)列的進(jìn)程切換太快了!
阻塞狀態(tài)
進(jìn)程像訪問的軟硬件資源未就緒,如果進(jìn)程等待鍵盤的資源,那么就把進(jìn)程鏈入到鍵盤pcb的等待隊(duì)列里。
如果進(jìn)程得到了鍵盤的資源,那么cpu就會(huì)把進(jìn)程鏈接到運(yùn)行隊(duì)列中(喚醒,把S改成R)
進(jìn)程也有等待隊(duì)列,進(jìn)程也會(huì)等待進(jìn)程
每一個(gè)設(shè)備都有自己的等待隊(duì)列,甚至不止一個(gè)
掛起
進(jìn)程的PCB和代碼數(shù)據(jù)都在內(nèi)存中,當(dāng)操作系統(tǒng)內(nèi)部的內(nèi)存資源嚴(yán)重不足時(shí),為了節(jié)省內(nèi)存資源,操作系統(tǒng)保留PCB,把代碼和數(shù)據(jù)交換到磁盤(外設(shè))中,當(dāng)資源就緒時(shí),把進(jìn)程放到運(yùn)行隊(duì)列時(shí),把代碼和數(shù)據(jù)重新放回內(nèi)存中。
2.具體Linux狀態(tài)如何維護(hù)的?
R 運(yùn)行態(tài)
不要用自己的感知和CPU的速度做對(duì)比!
等待外設(shè)大概率是S狀態(tài)
不涉及外設(shè)
R+ 前臺(tái)運(yùn)行
./myproc & 后臺(tái)運(yùn)行 后臺(tái)運(yùn)行只能kill殺掉
S狀態(tài) 阻塞態(tài) 淺度睡眠(可被喚醒)
情況1.等待某種資源就緒
情況2.主動(dòng)sleep,99%都在等待,1%是運(yùn)行打印,因?yàn)镃PU太快了
D狀態(tài) 深度睡眠 不響應(yīng)任何請(qǐng)求 阻塞態(tài)
dish sleep 磁盤 = disk
進(jìn)程交給磁盤寫入任務(wù),等待外設(shè)過程中,操作系統(tǒng)內(nèi)部?jī)?nèi)存嚴(yán)重不足,os把能置換的內(nèi)存都置換了,此時(shí)Os會(huì)殺掉進(jìn)程,導(dǎo)致磁盤寫入完成后的數(shù)據(jù)丟失。
但是磁盤寫入的數(shù)據(jù)很重要所以只要當(dāng)前進(jìn)程有寫入任務(wù)交給了磁盤,如果磁盤沒有辦法立馬響應(yīng)的話,需要進(jìn)程等待,這個(gè)進(jìn)程絕對(duì)不能以淺度睡眠的狀態(tài)等待,必須把自己設(shè)為D狀態(tài),任何人不能殺掉包括操作系統(tǒng)。
當(dāng)磁盤寫完數(shù)據(jù)告訴進(jìn)程時(shí),進(jìn)程把自己D變成R繼續(xù)運(yùn)行。
操作系統(tǒng)中如果看到1個(gè)D狀態(tài)進(jìn)程,在這種內(nèi)存嚴(yán)重不足,高IO磁盤壓力很大,那么操作系統(tǒng)就要掛了
如果內(nèi)存充裕,那么大概率是S狀態(tài)
while :; do ps ajx | head -1&& ps ajx | grep mycode | grep -v grep; sleep 1;done
D和S都是阻塞態(tài),操作系統(tǒng)是理論,實(shí)際有所差別
T && t
T和t已經(jīng)沒啥區(qū)別了
18-19號(hào)信號(hào),對(duì)進(jìn)程發(fā)送暫停繼續(xù)信號(hào)
S和T狀態(tài)有啥區(qū)別?
T叫做暫停,可能等待某種資源,或者就是想暫時(shí)暫停控制一下
T也可以理解為操作系統(tǒng)級(jí)別的阻塞狀態(tài)
t應(yīng)用場(chǎng)景
gdb打斷點(diǎn)調(diào)試時(shí),對(duì)進(jìn)程發(fā)送暫停信號(hào)進(jìn)行了暫停
X(dead)
進(jìn)程死亡 回收,瞬時(shí)狀態(tài)很難看到
Z(zombie)
一個(gè)進(jìn)程退出(死亡)時(shí)并不會(huì)立即釋放它的所有資源,它會(huì)維持一段時(shí)間,把資源交給父進(jìn)程讀取
僵死狀態(tài)(Zombies)是一個(gè)比較特殊的狀態(tài)。當(dāng)進(jìn)程退出并且父進(jìn)程(使用wait()系統(tǒng)調(diào)用,后面講)
沒有讀取到子進(jìn)程退出的返回代碼時(shí)就會(huì)產(chǎn)生僵死(尸)進(jìn)程
僵死進(jìn)程會(huì)以終止?fàn)顟B(tài)保持在進(jìn)程表中,并且會(huì)一直在等待父進(jìn)程讀取退出狀態(tài)代碼
只要子進(jìn)程退出,父進(jìn)程還在運(yùn)行,但父進(jìn)程沒有讀取子進(jìn)程狀態(tài),子進(jìn)程進(jìn)入Z狀態(tài)
問題1 : 父進(jìn)程怎么沒有僵尸呢?
父進(jìn)程的父進(jìn)程是Bash,當(dāng)程序結(jié)束時(shí),bash直接回收父進(jìn)程
問題2:子進(jìn)程為什么也結(jié)束了?
操作系統(tǒng)systemd or init 領(lǐng)養(yǎng)了子進(jìn)程
父進(jìn)程未回收子進(jìn)程,造成子進(jìn)程一直維護(hù)PCB
并且僵尸進(jìn)程會(huì)造成系統(tǒng)級(jí)內(nèi)存泄漏
如果進(jìn)程放在一個(gè)循環(huán)里,一直造成內(nèi)存泄露,雖然說最后進(jìn)程結(jié)束會(huì)被操作系統(tǒng)領(lǐng)養(yǎng)但是進(jìn)程運(yùn)行期間就不斷的內(nèi)存泄漏
孤兒進(jìn)程
父子進(jìn)程,父進(jìn)程先退出,子進(jìn)程的父進(jìn)程會(huì)被改成1號(hào)進(jìn)程(操作系統(tǒng)),
linux中對(duì)應(yīng)掛起狀態(tài)
掛起后用戶感知不到,就像銀行存錢,銀行拿著錢干什么了,我們不知道,用的時(shí)候再還給你
但是一般對(duì)應(yīng)的是T狀態(tài) 或者 S狀態(tài)
Linux中tast_struct(pcb)結(jié)構(gòu)體對(duì)象組織交叉
Linux中tast_struct(pcb)結(jié)構(gòu)體對(duì)象的組織是交叉在一起的,一個(gè)進(jìn)程既屬于某個(gè)多叉樹又屬于某一個(gè)雙向鏈表,所以一個(gè)結(jié)點(diǎn)即可以放到多叉樹又可以放到鏈表中。
Linux的設(shè)計(jì)是比較優(yōu)雅的
Linux并沒有像我們數(shù)據(jù)結(jié)構(gòu)一樣把數(shù)據(jù)放到strue node中,而是把node放到tast_struct里面串起來
利用0號(hào)地址結(jié)構(gòu)體尋找node地址偏移量,再用start-偏移量,找到tast_struct的地址
還要注意指針-指針需要無腦轉(zhuǎn)int or char*,不然指針-指針是元素個(gè)數(shù)
優(yōu)雅在于不同于task_struct的結(jié)構(gòu)體與other類型也可以被鏈表node所鏈接起來
并且tast_struct可以鏈接到不同結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)中,雙向鏈表,二叉樹,只需要在tast_struct中放入struct node
進(jìn)程優(yōu)先級(jí)
什么是優(yōu)先級(jí)?
優(yōu)先級(jí)(對(duì)于資源的訪問,誰先訪問,誰后訪問) vS 權(quán)限(能與不能)
優(yōu)先級(jí)是已經(jīng)有權(quán)限了決定誰先誰后
為什么要有優(yōu)先級(jí)?
因?yàn)橘Y源是有限的,進(jìn)程是多個(gè)的,注定了,進(jìn)程之間是競(jìng)爭(zhēng)關(guān)系! —競(jìng)爭(zhēng)性
操作系統(tǒng)必須保證大家良性競(jìng)爭(zhēng),確認(rèn)優(yōu)先級(jí)
如果我們進(jìn)程長(zhǎng)時(shí)間得不到CPU資源,該進(jìn)程的代碼長(zhǎng)時(shí)間無法得到推進(jìn)—該進(jìn)程的饑餓問題
怎么辦?
查優(yōu)先級(jí)
ps -l
默認(rèn)打開當(dāng)前終端啟的進(jìn)程
ps -al
打開所有終端進(jìn)程
更改優(yōu)先級(jí)
方式1.nice
方式2.renice
方式1.top后按r
每次更改都會(huì)PRI都會(huì)從80開始
同樣Linux限制了優(yōu)先級(jí)的更改的范圍
操作系統(tǒng)是如何根據(jù)優(yōu)先級(jí),開展的調(diào)度呢???
位圖
為了方便理解先前運(yùn)行隊(duì)列沒有優(yōu)先級(jí),現(xiàn)在有了優(yōu)先級(jí)該如何確定各個(gè)進(jìn)程的優(yōu)先級(jí)呢?
Linux的做法非常優(yōu)雅:
利用指針數(shù)組tast_struct* running[140]來指向task_struct,PRI是60的就放入100號(hào)下標(biāo)位,同樣的PRI鏈接到后面排隊(duì),不同的PRI就鏈入到對(duì)應(yīng)[60,99]->數(shù)組中[100,139]這40個(gè)位置之中,數(shù)組中[0,99]是其他種類進(jìn)程用的(我們大概率用不上)
當(dāng)running隊(duì)列調(diào)度時(shí)從左往右,從上往下,確定了優(yōu)先級(jí)!
新來的或者被拔下來的進(jìn)程都放到waiting數(shù)組中,當(dāng)running隊(duì)列運(yùn)行完(空了),交換二級(jí)指針run和wait,run永遠(yuǎn)認(rèn)為指向運(yùn)行隊(duì)列,wait永遠(yuǎn)指向空閑隊(duì)列
我怎么知道我當(dāng)前運(yùn)行隊(duì)列為空了呢?
遍歷太慢了!
Linux內(nèi)核的O(1)調(diào)度算法!
利用位圖來判斷,40個(gè)位置只需要5字節(jié)的bit位,所以char bits[5];
規(guī)定數(shù)組最右bit位是100號(hào)位
判斷這40個(gè)bit位是不是等于0,就做到近乎O(1)