進程及線程

程序:存儲在磁盤上的二進制可執行文件。是靜態的,一個程序可生成多個進程。

進程:一個正在運行的程序,是系統進行資源分配的基本單位。是動態的,是一次程序的實例化。

Linux進程描述符:struct task_struct

進程在其生命週期存在的狀態:

就緒:所有資源準備完成,等待cpu空閒的狀態

運行:在cpu上真正執行的狀態

阻塞:等待某些事件發生,時間未發生前,不能被cpu調度的狀態。

進程由進程控制塊和實體組成:

 

就緒----》運行:系統進行進程調度

運行---》就緒:分配給進程的時間片用完

運行---》阻塞:需要某些事件發生才能運行(阻塞函數)

阻塞---》就緒:等待的事件已經發生,只能轉到就緒態,不能直接轉到運行態

除此之外,進程還有創建,退出,就緒/掛起,阻塞/掛起等狀態

線程:進程內部的一條執行路··徑,是系統進行調度的基本單位。

在linux中線程的實現:在Linux中線程的實現十分獨特,從內核的角度來說,並沒有線程的概念,Linux把所有的線程都當作進程來實現,內核並沒有準備特別的調度算法或是定義特別的數據結構來表示線程。相反,線程僅僅被當做一個與其它進程共享某些資源的進程。每個線程都有唯一隸屬於自己的task_struct,所以在內核中,它看起來就像一個普通的進程(只是該進程和其他一些進程共享某些資源,如地址空間)

僵死進程:子進程先於父進程結束,父進程沒有獲取子進程的退出碼,此時,子進程變成僵死進程。

對僵死進程的處理方式:父進程調用wait獲得退出碼,或父進程先結束,讓init進程接管子進程。

fork()複製過程:一個現有進程調用fork函數創建一個新的進程(複製進程 寫時拷貝  以頁爲單位)

父進程打開的文件,會被複制到子進程中,父子進程共享打開的文件。

1)分配pid

2)分配進程描述符也就是PCB,同時分配好內核棧

3)複製進程實體,即:打開的文件,工作目錄,信號信息,進程地址空間等等

4)用父進程內核棧上存放的現場信息,初始化爲子進程的現場信息,並將eax置爲0

5)將父進程的時間片分子進程一半,設置進程狀態爲就緒。

fork哪些被複制,哪些被共享?

參考博客:https://blog.csdn.net/qq_35191331/article/details/79803548

https://blog.csdn.net/xy010902100449/article/details/44851453

複製資源:打開的文件描述符,子進程獲得父進程的數據空間,堆和棧的副本,注意是子進程擁有的副本,並不共享這些存儲空間的部分。打開的文件  實際用戶ID、實際組ID、有效用戶ID、有效組ID   添加組ID
進程組ID  對話期ID  控制終端。   設置-用戶-ID標誌和設置-組-ID標誌   當前工作目錄
根目錄   文件方式創建屏蔽字   信號屏蔽和排列   對任一打開文件描述符的在執行時關閉標誌
環境    連接的共享存儲段(共享內存)  資源限制

共享資源:代碼段,數據段和用戶堆棧內存空間並沒有複製一份,而是與子進程共享。

父進程設置的文件鎖,互斥鎖等鎖被共享

實際用戶ID在某一時刻可具有的最大進程數:CHILD_MAX     整形能表示的範圍內  32768

關於fork的一些筆試題:

0

分析:fork()||fork(),當第一個fork爲1時,第二個fork不執行,此時第一個fork已經複製出一個fork,當第一個fork爲0,第二個fork執行,第二個fork又複製出一個fork,所以最後結果打印出來爲三個A.

分析:在此次程序中,當i=0時,fork進行一次複製打印出兩個A,當i=1時,此時自己的fork進行復制,打印出兩個A,再加上i=0時已經生成的兩個fork再進行運行,又生成2個A,所以總共是6個A。

分析:跟個程序不同的是,此次生成的A並沒有進行輸出,而是存放再緩衝區中,所以多出的兩個A應該是進行fork時裏面生成的緩衝區的A。

分析:第一次執行printf生成一個A,存放在緩衝區中,沒有進行輸出,然後進行write執行,write進行程序的直接輸出,fork後,print裏面沒有輸出的A也進行fork,所以得到AA,程序輸出爲BAA。

關於函數write(1,"B",1);第一個1表示標準輸出,B爲字符串,後面1表示一個字節(長度)

write表示直接投到屏幕上(系統調用),而printf  /n.fflush表示將數據沒有直接打印出來,而是存放在緩衝區中。

文件描述符:open打開一個文件,會得到一個文件描述符open,read,write,close.

信號:signal:改變信號的響應方式。

kill:發送信號

默認:SIG_DFL

忽略:SIG_IGV

自定義:fun

SIGCHID:子進程狀態發生,發給父進程

SIGINT:ctrl+c

kill pid:發送信號

kill -9 pid:發送9號,9號不允許改變響應方式。

 

 

 

                       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章