fork是乙個系統呼叫,根據系統呼叫的流程,最後在sys_call_table中找到相應的系統呼叫sys_fork。
根據syscall_define0這個巨集的定義,下面**代表了sys_fork
syscall_define0
(fork)
sys_fork會呼叫_do_fork。
long
_do_fork
(unsigned
long clone_flags,
unsigned
long stack_start,
unsigned
long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr,
unsigned
long tls)..
....
_do_fork裡面做的第一件大事就是copy_process,如果所有的資料結構從頭建立乙份太麻煩,所以採用複製方式。
根據task_struct的結構圖,對比看著如何乙個個複製
copy_process基本要結束了,上面的組建也初始化差不多了
_do_fork要做的第二件大事是wake_up_new_task,新任務槓桿共建立,有沒有機會搶占別人,獲得cpu呢
void
wake_up_new_task
(struct task_struct *p)
首先將程序的狀態設定為task_running
activate_task函式中會呼叫enqueue_task
static
inline
void
enqueue_task
(struct rq *rq,
struct task_struct *p,
int flags)
如果是cfs的排程類,則執行相應的enqueue_task_fair
static
void
enqueue_task_fair
(struct rq *rq,
struct task_struct *p,
int flags)
在 enqueue_task_fair 中取出的佇列就是 cfs_rq,然後呼叫 enqueue_entity。
在 enqueue_entity 函式裡面,會呼叫 update_curr,更新執行的統計量,然後呼叫 __enqueue_entity,將 sched_entity 加入到紅黑樹裡面,然後將 se->on_rq = 1 設定在佇列上。
回到 enqueue_task_fair 後,將這個佇列上執行的程序數目加一。然後,wake_up_new_task 會呼叫 check_preempt_curr,看是否能夠搶占當前程序。
在 check_preempt_curr 中,會呼叫相應的排程類的 rq->curr->sched_class->check_preempt_curr(rq, p, flags)。
對於 cfs 排程類來講,呼叫的是 check_preempt_wakeup。
static
void
check_preempt_wakeup
(struct rq *rq,
struct task_struct *p,
int wake_flags)
return
;preempt:
resched_curr
(rq);.
....
.}
如果新建立的程序應該搶占父程序,在什麼時間搶占呢?別忘了 fork 是乙個系統呼叫,從系統呼叫返回的時候,是搶占的乙個好時機,如果父程序判斷自己已經被設定為 tif_need_resched,就讓子程序先跑,搶占自己。
fork 系統呼叫的過程咱們就解析完了。它包含兩個重要的事件,乙個是將 task_struct 結構複製乙份並且初始化,另乙個是試圖喚醒新建立的子程序。
如何接手乙個新專案
專案好與不好,它就在那裡 架構優雅或者醜陋,它就在那裡 注釋有或者沒有,它還在那裡 文件亂或者不亂,它始終都在那裡。不論它是什麼樣子的,線上就那樣跑著。一般來講,專案分為兩種 2 為技術服務的專案,比如開源中介軟體專案 dubbo spring cloud 各種資料庫中介軟體 各種快取方案等 首先說...
用pycharm建立乙個新專案
2.如何建立自己的專案 from flask import flask c 在views下建立檢視函式 from flask import blueprint,render template blue blueprint main name blue.route def index return r...
使用Vue建立乙個新專案
保證已經安裝好了node npm vue等工具,將路徑設定為想要建立新專案的資料夾路徑 2 關於npm與cnpm npm包管理器,是整合在node中的,node環境安裝完成,npm包管理器也有了。由於有些npm有些資源被遮蔽或者是國外資源的原因,經常會導致後面用npm安裝依賴包的時候失敗,所有我還需...