亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 2010 | 回復(fù): 7
打印 上一主題 下一主題

對(duì)進(jìn)程的一些初略總結(jié) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2007-09-04 17:46 |只看該作者 |倒序?yàn)g覽
前幾天問(wèn)了關(guān)于shell里"."和":"的問(wèn)題(http://72891.cn/viewthr ... =bzw2000&page=1), 在版主的推薦下, 看了網(wǎng)中人前輩的http://72891.cn/viewthr ... ;page=6#pid1583329. 感覺(jué)對(duì)進(jìn)程的理解不夠, 這兩天在網(wǎng)上查了點(diǎn)資料, 看了點(diǎn)書(shū), 現(xiàn)在總結(jié)一下(當(dāng)然也有新的問(wèn)題):
  因?yàn)閟hell本身是一個(gè)進(jìn)程, 所以我們這里把shell進(jìn)程抽象為進(jìn)程1(P1).
  先來(lái)說(shuō)一下一個(gè)進(jìn)程本身在系統(tǒng)中的上下文環(huán)境. 一個(gè)進(jìn)程通常包括:
      * CPU寄存器組
      * GDT表中的四項(xiàng): OS代碼段描述符, OS數(shù)據(jù)段描述符(指向OS代碼段和數(shù)據(jù)段, 所有進(jìn)程共享), 本進(jìn)程的ldt描述符, 本進(jìn)程的tss描述符(指向后面提到的PCB中的ldt段和tss段)
      * OS代碼段, OS數(shù)據(jù)段: 用戶進(jìn)程可通過(guò)系統(tǒng)調(diào)用int 0x80訪問(wèn)這些代碼和數(shù)據(jù)
      * 進(jìn)程控制塊(即PCB): 大小通常是一頁(yè)內(nèi)存, 在內(nèi)核模塊的kernel代碼塊中, 包含了所有本進(jìn)程需要的信息. 其中包括進(jìn)程號(hào), 各進(jìn)程時(shí)間, ldt段(內(nèi)容有指向本進(jìn)程私有代碼段和數(shù)據(jù)段的描述符), tss段(本進(jìn)程的上下文, 進(jìn)程切換時(shí)有用), 打開(kāi)文件信息等.
      * 內(nèi)核棧: 與PCB在同一頁(yè)內(nèi)存中, 故大小為(一頁(yè)內(nèi)存-PCB的大小).
      * 私有代碼段, 數(shù)據(jù)段: 進(jìn)程本身的代碼和數(shù)據(jù)
      * 頁(yè)目錄(由CR3指定, 所有進(jìn)程共享)和頁(yè)表
   再說(shuō)fork/exec的區(qū)別:
      在shell里執(zhí)行"1.sh fork", 相當(dāng)于在P1里fork一個(gè)新進(jìn)程P2, 然后在P2里exec 2.sh. 具體為:
        * P1通過(guò)系統(tǒng)調(diào)用int 0x80創(chuàng)建P2(功能號(hào)為_(kāi)_NR_fork, 即fork). fork的過(guò)程從本質(zhì)上說(shuō)就是構(gòu)建新進(jìn)程本身的GDT項(xiàng)(2項(xiàng)), PCB和頁(yè)表三項(xiàng). 基本過(guò)程如下:
             {
                 struct task_struct *p;                //p即為新進(jìn)程P2的PCB
                 
                 /* 1. 先復(fù)制P1的PCB, 然后進(jìn)行修改*/
                 p <= get_free_page();                 //在主內(nèi)存申請(qǐng)一頁(yè)空閑內(nèi)存, 用來(lái)存放PCB
                 *p = *current;                        //current指向P1的PCB
                 p->pid <= P2進(jìn)程的進(jìn)程號(hào);
                 設(shè)置 p->tss;                          //不知道除了進(jìn)程切換會(huì)用到tss, 還有什么情況會(huì)用到??
                 設(shè)置 p其他一些成員(比如進(jìn)程時(shí)間, 優(yōu)先級(jí), 時(shí)間滴答數(shù)等), 具體可以參考fork.c里的copy_process;
                 設(shè)置 p->ldt, 使之指向P2的私有代碼段, 數(shù)據(jù)段;
                 
                 /* 2. 復(fù)制頁(yè)表 (參考memory.c中相關(guān)程序)*/
                 copy_page_tables();                  //  此函數(shù)的主要作用就是為進(jìn)程2復(fù)制進(jìn)程1的頁(yè)目錄項(xiàng), 申請(qǐng)新頁(yè)表,
                                                      //使新頁(yè)表項(xiàng)指向父進(jìn)程的空間(因?yàn)閘inux采用了寫(xiě)時(shí)復(fù)制機(jī)制).
                                                      //  此和前面說(shuō)的p->ldt一起使用, 就實(shí)現(xiàn)了新進(jìn)程2的地址映射:
                                                      // p->ldt指明了P2的線性地址空間范圍, 而頁(yè)表又把此線性地址范圍
                                                      // 映射到P1的物理地址范圍內(nèi), 直到P1或P2對(duì)此物理地址范圍有寫(xiě)入
                                                      //操作, 才會(huì)使P2映射到新的物理地址, 否則P1和P2就共享同一塊物理地址
                                                      //空間.
               
                /* 3.  設(shè)置GDT表中新進(jìn)程P2的ldt,tss描述符: 使它們指向PCB中l(wèi)dt和tss*/
                set_tss_desc();
                set_ldt_desc();              
                 
             }   
         * 然后P2也通過(guò)系統(tǒng)調(diào)用int 0x80加載P2的代碼(功能號(hào)為_(kāi)_NR_execve, 即exec). 主要作用是加載新可執(zhí)行程序, 覆蓋原來(lái)的代碼和數(shù)據(jù). 具體為:
             /* 以下具體代碼可參考exec.c中do_execve()函數(shù) */
             {
                讀取新進(jìn)程執(zhí)行文件第一塊數(shù)據(jù)(即頭結(jié)構(gòu). 不過(guò)怎么讀取的我也沒(méi)看懂 ), 根據(jù)頭結(jié)構(gòu)信息判斷是shell腳本文件還是二進(jìn)制可執(zhí)行文件;
               
                如果是可執(zhí)行文件(ELF), 則:
                   1. 把新進(jìn)程的環(huán)境變量(envp)和參數(shù)(argv)放入一組臨時(shí)物理頁(yè)面中(環(huán)境參數(shù)空間), 并把這些頁(yè)面的物理地址對(duì)應(yīng)地填入一個(gè)數(shù)組page[]中.
                      這就相當(dāng)于頁(yè)表與線性地址的關(guān)系. 每個(gè)page[]項(xiàng)包含物理頁(yè)面的物理地址, 對(duì)應(yīng)關(guān)系即為頁(yè)面的線性地址對(duì)page的索引.
                   2. 接下來(lái)是把和原來(lái)用戶代碼段和數(shù)據(jù)段相關(guān)的頁(yè)表、頁(yè)目錄項(xiàng)清0, 即釋放原來(lái)用戶的代碼和數(shù)據(jù)段. 這樣, 當(dāng)前進(jìn)程P2就只有PCB所占的那頁(yè)物理內(nèi)存了.
                      這里再?gòu)?qiáng)調(diào)一下是釋放原來(lái)"用戶"的私有代碼和私有數(shù)據(jù), 并沒(méi)有釋放OS代碼和數(shù)據(jù), 否則程序就執(zhí)行不下去拉.
                   3. 重新設(shè)置新用戶程序代碼段(ldt[1]),數(shù)據(jù)段(ldt[2])的基址和限長(zhǎng). 還記得嗎, ldt是在PCB中的. 所以這步是修改PCB.
                      再把page[]中對(duì)應(yīng)的頁(yè)面放到代碼段的最后(大家可以參考ELF格式).  然后修改頁(yè)目錄和頁(yè)表, 使其頁(yè)表項(xiàng)指向這些物理頁(yè)面. 也就是說(shuō),
                      現(xiàn)在新進(jìn)程用戶空間只有參數(shù)環(huán)境空間這些物理頁(yè)面.
                   4. 通過(guò)分配新的物理頁(yè)面創(chuàng)建用戶堆棧, 把以上這些環(huán)境參數(shù)項(xiàng)壓入堆棧. 現(xiàn)在進(jìn)程用戶空間有參數(shù)環(huán)境空間這些物理頁(yè)面, 和堆棧的物理頁(yè)面.
                      其他部分(如代碼,數(shù)據(jù)等)都沒(méi)有物理頁(yè)面。
                   5. 修改PCB中current的一些字段, 并修改內(nèi)核棧原來(lái)的eip和esp, 使得eip指向可執(zhí)行文件的入口,esp指向新堆棧頂端. 注意到這里為進(jìn)程還是沒(méi)為新程序的
                      代碼和數(shù)據(jù)分配物理頁(yè)面. 這只有當(dāng)執(zhí)行到新代碼時(shí), 發(fā)現(xiàn)缺頁(yè)異常, 才會(huì)分配.
               
                如果是shell腳本, 則:
                    過(guò)程和以上差不多, 就是要逐條解析腳本里程序名.
               
               
             }
      在bash(進(jìn)程)里執(zhí)行"1.sh exec", 相當(dāng)于在P1里exec 2.sh. 即上面所說(shuō)的第二步.   
      
      問(wèn)題來(lái)了, bash執(zhí)行完1.sh exec,  bash的代碼應(yīng)該被替代為1.sh的代碼, 即應(yīng)該已經(jīng)沒(méi)有bash進(jìn)程了. 但為什么bash進(jìn)程執(zhí)行完1.sh后, 還能繼續(xù)作為bash shell運(yùn)行? 它是怎么從1.sh恢復(fù)為bash的?   是不是我前面理解錯(cuò)了啊?

      還有就是":"也告訴我一下是什么命令吧, 查不到

[ 本帖最后由 bzw2000 于 2007-9-4 17:50 編輯 ]

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2007-09-04 18:18 |只看該作者
bash是命令行解釋器.

啟動(dòng)  -> 掛起  ->  停止.

[ 本帖最后由 linux_paly 于 2007-9-4 18:20 編輯 ]

論壇徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亞冠之浦和紅鉆
日期:2015-06-23 19:10:532015亞冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16賽季CBA聯(lián)賽之山東
日期:2016-01-31 18:25:0515-16賽季CBA聯(lián)賽之四川
日期:2016-02-16 16:08:30程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-06-29 06:20:002017金雞報(bào)曉
日期:2017-01-10 15:19:5615-16賽季CBA聯(lián)賽之佛山
日期:2017-02-27 20:41:19
3 [報(bào)告]
發(fā)表于 2007-09-04 21:05 |只看該作者
問(wèn)題來(lái)了, bash執(zhí)行完1.sh exec,  bash的代碼應(yīng)該被替代為1.sh的代碼, 即應(yīng)該已經(jīng)沒(méi)有bash進(jìn)程了. 但為什么bash進(jìn)程執(zhí)行完1.sh后, 還能繼續(xù)作為bash shell運(yùn)行? 它是怎么從1.sh恢復(fù)為bash的?   是不是我前面理解錯(cuò)了啊?

bash fork一個(gè)子進(jìn)程subshell,在subshell中執(zhí)行1.sh

:是一個(gè)什么也不干的程序,正常返回狀態(tài)為1

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2007-09-04 21:33 |只看該作者
原帖由 linux_paly 于 2007-9-4 18:18 發(fā)表
bash是命令行解釋器.

啟動(dòng)  -> 掛起  ->  停止.


bash是命令行解釋器,bash也是進(jìn)程啊

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2007-09-04 21:35 |只看該作者
原帖由 waker 于 2007-9-4 21:05 發(fā)表
問(wèn)題來(lái)了, bash執(zhí)行完1.sh exec,  bash的代碼應(yīng)該被替代為1.sh的代碼, 即應(yīng)該已經(jīng)沒(méi)有bash進(jìn)程了. 但為什么bash進(jìn)程執(zhí)行完1.sh后, 還能繼續(xù)作為bash shell運(yùn)行? 它是怎么從1.sh恢復(fù)為bash的?   是不是我前面理解 ...



bash fork 我知道,  但我說(shuō)的是1.sh exec,  這應(yīng)該在bash本身進(jìn)程里運(yùn)行吧

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2007-09-07 11:17 |只看該作者
自己頂一下

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2007-09-07 11:39 |只看該作者
我的理解是:bash先f(wàn)ork()一個(gè)子shell,然后這個(gè)子shell執(zhí)行execl('/bin/bash','bash','1.sh',(char*)0);bash本身并不執(zhí)行。

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2007-09-07 12:41 |只看該作者
原帖由 sunceenjoy 于 2007-9-7 11:39 發(fā)表
我的理解是:bash先f(wàn)ork()一個(gè)子shell,然后這個(gè)子shell執(zhí)行execl('/bin/bash','bash','1.sh',(char*)0);bash本身并不執(zhí)行。


你說(shuō)的這種情況是屬于"1.sh fork".
"1.sh exec"應(yīng)該是在父shell里執(zhí)行, 否則它是怎么改變父shell(用進(jìn)程號(hào)區(qū)別)里的環(huán)境變量的呢?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP