linux程序和程式

2022-09-11 19:39:14 字數 3278 閱讀 7133

學號245

再中1235行我們可以看到乙個很長的tast_struct結構體的定義。下圖是部分截圖:

程序管理是作業系統提供的最基本的功能之一,為了描述程序,用程序控制塊pcb來唯一地定義乙個程序。tast_struct中定義了程序的標識、程序的狀態、程序的排程策略等。如:狀態state用-1、0、>0表示三種狀態。其中,各部分依次是:程序的底層資訊、指向記憶體區域描述符的指標、程序相關的tty裝置、當前目錄、指向檔案描述符的指標、接收到的訊號。

fortvfortclone都可以用來建立乙個新的程序,但其實他們都是呼叫了do_fork函式實現的。

long do_fork(unsigned long clone_flags,

1624 unsigned long stack_start,

1625 unsigned long stack_size,

1626 int __user *parent_tidptr,

1627 int __user *child_tidptr)

1628

1650

1651 p = copy_process(clone_flags, stack_start, stack_size,

1652 child_tidptr, null, trace);

1653 /*

1654 * do this prior waking up the new thread - the thread pointer

1655 * might get invalid after that point, if the thread exits quickly.

1656 */

1657 if (!is_err(p))

1674

1675 wake_up_new_task(p);

1676

1677 /* forking complete and child started to run, tell ptracer */

1678 if (unlikely(trace))

1679 ptrace_event_pid(trace, pid);

1680

1681 if (clone_flags & clone_vfork)

1685

1686 put_pid(pid);

1687 } else

1690 return nr;

1691}

從**中可以看出,do_fork呼叫了copy_process建立程序,這個函式又很長,大概400行左右。

它做了這麼幾件事:

複製當前的tast_struct;

初始化程序,並將狀態設為task_running;

複製父程序的所有資訊;

呼叫copy_thread初始化子程序的核心棧;

為新的程序分配設定新的pid;

linux環境下,fork系統呼叫將會建立乙個與當前task完全一樣的新task,直到應用程式呼叫exec*系列的glibc庫函式最終呼叫execve系統呼叫之後,linux核心才開始真正裝載elf可執行檔案(映像檔案)。execve核心入口為sys_execve,隨之呼叫do_execve將查詢這個可執行檔案,如果找到則讀取elf可執行檔案的前128個位元組,然後呼叫search_binary_handle通過elf檔案頭中的e_ident得到可執行檔案的magic number,判斷出這是乙個什麼型別的可執行檔案,並呼叫不同可執行檔案的裝載處理程式,對於elf可執行檔案而言,其裝載處理程式為load_elf_binary,這個函式將會把execve系統呼叫的返回位址修改為elf可執行檔案的入口點,對於靜態鏈結得到的elf檔案即檔案頭中定義的e_entry,對於動態鏈結得到的elf可執行檔案則是動態鏈結器。一步一步返回到sys_execve之後,因為返回位址已經被修改為了elf程式入口位址了,所以系統呼叫返回到使用者態之後,eip指令暫存器將直接跳轉到elf程式入口位址,程式開始執行,裝載完成。

過程如下:

fork -> execve() -> sys_execve() -> do_execve()

核心執行程序切換由兩步組成:

切換全域性目錄以安裝乙個新的位址空間;

切換核心態堆疊和硬體上下文,因為硬體上下文提供了核心執行新程序所需要的所有資訊,包含cpu暫存器。

switch_to()

/* context switching is now performed out-of-line in switch_to.s */

extern struct task_struct *__switch_to(struct task_struct *,

struct task_struct *);

#define switch_to(prev, next, last)\

do while (0)

其中呼叫了__switch_to函式:

__switch_to

__switch_to(

struct task_struct *prev_p,

struct task_struct *next_p)

switch_to函式中,prevnext是輸入引數,假設核心決定暫停程序a而啟用程序b,在schedule函式中,prev指向a的描述符,而next指向b的程序描述符。switch_to巨集一旦使a暫停,a的執行流就被凍結。

程序管理是作業系統提供的最基本的功能之一,通過do_fork建立新程序。當核心需要切換到另乙個程序時候,需要儲存當前程序的所有狀態,即當前程序的上下文,這樣當再次執行該程序時候,能夠恢復之前的狀態繼續執行。

程式和程序

程式 或者狹義上講可執行檔案 是乙個靜態的概念,它就是一些預先編譯好的指令合資料集合的乙個檔案 程序則是乙個動態的概念,它是程式執行時的乙個過程,很多時候把動態庫叫做執行時 runtime 也有一定的含義。有人做過乙個很有意思的比喻,說把程式和程序的概念跟做菜相比較的話,那麼程式就是菜譜,計算機的c...

linux程式管理和程序(1)

什麼是程序 乙個程式被載入到記憶體中執行,那麼在記憶體中的那個資料就被稱為程序,所有系統上面跑的資料都以程序的型別存在。在linux系統中,觸發任何乙個事件,系統都會定義為乙個程序,並且給予這個程序乙個id,稱為pid,同時觸發這個程序的使用者與相關屬性關係,給予這個pid一組有效的許可權設定。舉個...

linux程式守護程序(shell)

使用shell每秒檢測一次程式是否在執行,如果沒有執行則自動啟動程式 bin bash 配置檔案路徑 configfile 1 config settings.ini slash restartlog daemon shopt s expand aliases alias datetime date...