linuxfork
❶ linux中的fork函數到底做了什麼事
額........每啟動一個進程並不一定要執行fork.fork只是系統最後封裝的一個系統調用.你在程序里不使用fork的話.使用其它方式啟動進程.就不是fork.fork族裡有很多函數...............exec也可替換當前進程......系統內核里生成一個進程用的是clone這個函數.
就比如要蓋個房子.一個人干,要先挖土再調水泥再擺磚頭再蓋牆這樣一步一步做.但是如果有多個人.就是可以多個人同時做這些事,一個挖土,一個調水泥.一個擺磚頭.這樣就省了很多時間.進程也是如此.fork的作用就是創建新進程.
這么多人一起蓋房子,總不能各自蓋各自的,需要大家協調來做.不能土沒挖好就擺磚,沒放磚就抹水泥一樣.這個時候需要一個工頭來管理大家.工頭通過每個人的名字來指揮每個人幹活.進程就通過pid來指揮一個進程幹活.工人需要知道自己的工頭是誰,好向他報告碰到的情況.進程需要知道自己的父進程是誰報告自己的情況.
這樣就明白fork為何要返回進程的id了吧?fork是不會返回父進程的id的.
工頭找了一個新工人幹活.從工頭知道這個新工人的名字時刻開始,新工人就會投入這個團隊一起幹活了.fork返回pid的時候就表示這個進程在這個進程團隊里了.工頭可以直接告訴工人要干什麼而不會讓其他工人誤以為這是自己的活.但是程序並沒有這么智能.這個時候就需要有一個狀態(if(!pid){....這是工人乾的活...})表明這個工人的代碼從什麼位置開始,到什麼位置結束.
❷ linux fork 會共享哪些東西
fork()不僅創建出與父進程代碼相同的子進程,而且父進程在fork執行點的所有上下文場景也被自動復制到子進程中,包括:
—全局和局部變數
—打開的文件句柄
—共享內存、消息等同步對象
由於pipe調用相當於創建了2個文件句柄,因此在fork後這兩個句柄也被自動復制到子進程中,對這兩個句柄的操作效果與在主進程中的操作效果是一致的,這就使父子進程之間很容易通過該機制實現數據交換,如:
假設pipe產生的句柄為P[0],P[1],在fork後父子進程都擁有了P[0],P[1]句柄,那麼:
—父進程可向自己的P[1]中寫入數據,子進程從P[0]中即可讀出該數據;切記此時父進程不能也從P[0]讀數據,否則自己寫入的數據可能先被自己讀走了
—反之亦然,子進程向P[1]中寫入數據後,父進程從P[0]中可讀出該數據;切記此時子進程不要從P[0]讀走數據
你可能難以理解為什麼進程內部的數據讀寫會被傳遞到另一個進程,但別忘了,pipe匿名管道和文件,socket等一樣是屬於操作系統的管理對象,對其進行讀寫都是由OS的內核代碼來進行控制的。在父進程調用pipe創建出管道後,該管道對象是存儲在OS內部的,父進程得到的P[0]和P[1]都只是對該對象的引用(相當於指針);在fork出子進程後,子進程復制出的也只是同一個指針,所指向的還是OS中的同一個對象,這就是為什麼父子進程能通過其進行互相通信的原因。
❸ linux fork() 進程問題
沒看明白你是怎麼理解的
就按照你的代碼示例來說, 這段代碼從A進程fork一個B進程出來,運行結果是列印4行消息
child id xxx1 // pid of process A
parent id xxx2 // pid of A's parent process
child id xxx3 // pid of process B
parent id xxx4 //pid of B's parent process, exactly equal to the pid of process A
以上這四行輸出有可能A在B的前面,或者B在A的前面,不確定(如果你的CPU是多核);但child總在parent的前面。
事實上關於fork的理解是這樣的, A fork一個進程B出來, A和B都要接著往下運行,但是一般來說A和B是要運行不同的代碼的,那這時候fork執行完接著執行下一句的時候,就需要首先知道當前的context是在A進程中還是在B進程中, 這樣才能確定接著執行什麼。 所以fork就需要返回兩次, 確切的講是在A和B的context中分別返回一次,在A的context中返回的是子進程的pid, 在B的context中返回0,所以創建進程時往往會這樣寫
int ret = fork();
if(0 == ret)
{
printf("hey, I am the child -- Process B\n");
//start to do what you want to handle in Process B
}
else //if ret > 0
{
printf("hey, I am the parent -- Process A\n");
//continue doing what you are working on in Process A
}
通過判斷 fork的返回值來確定當前context是屬於哪個進程,並執行相應的代碼,開始在兩個進程中做各自的事情。
❹ 關於Linux的fork()
= OR ==
你初學者吧,請把賦值 =
和 == 值比較 搞清楚啊
= value assignment
== value compare
❺ linux下的fork函數
不止三個,子進程仍然在循環體內,所以子進程也會根據它的i值來做循環,然後fork子進程的子進程,但是你的程序也有問題,父進程列印後沒有等待子進程運行結束就return了,這樣有些子進程還來不僅運行就退出了。所以你的程序的輸出結果是不可靠的,也是可能是隨機的(其結果會根據運行時操作系統的具體調度的不同而不同)。所以我給你改了一下,這樣就能讓所有被fork的子進程(包括這些子進程再次fork出來的子進程)都有機會運行。
int main()
{
int i;
int my_pid;
int chld_pid;
for( i= 0; i< 3; i++)
{
chld_pid= fork();
if(chld_pid== 0) {
my_pid = getpid();
printf("i = %d, child pid %d\n", i, my_pid);
}
else {
my_pid = getpid();
printf("i = %d, parent pid %d, child pid %d\n",i, my_pid, chld_pid);
wait(0); /*waiting for the completion of child */
}
}
return 0;
}
運行後的結果為:
i = 0, parent pid 5294, child pid 5295
i = 0, child pid 5295
i = 1, parent pid 5295, child pid 5296
i = 1, child pid 5296
i = 2, parent pid 5296, child pid 5297
i = 2, child pid 5297
i = 2, parent pid 5295, child pid 5298
i = 2, child pid 5298
i = 1, parent pid 5294, child pid 5299
i = 1, child pid 5299
i = 2, parent pid 5299, child pid 5300
i = 2, child pid 5300
i = 2, parent pid 5294, child pid 5301
i = 2, child pid 5301
這樣你就可以看到,實際上有7個子進程被fork出來,其中有3個是被真正的父進程(5294)fork出來的,而其餘的則是被5294的子進程(甚至子進程的子進程)所fork出來的。其中的邏輯關系從列印出來的進程號就可以一目瞭然了,我就不贅述了。
❻ linux下的fork()運用
fork()創建一個子進程,fork()進入內核,調用一次返回兩次,如果返回的pid == 0子進程先返回,如果pid > 0(此時返回的是子進程的pid),父進程先返回。至於子進程和父進程哪個先返回,要看內核的調度演算法。輸出次序亂序,都有可能。父進程和子進程是並發執行的。
❼ Linux下fork,vfork,clone和exec的區別
前三個和最後一個是兩個類型。前三個主要是Linux用來創建新的進程(線程)而設計的,exec()系列函數則是用來用指定的程序替換當前進程的所有內容。所以exec()系列函數經常在前三個函數使用之後調用,來創建一個全新的程序運行環境。Linux用init進程啟動其他進程的過程一般都是這樣的。
下面說fork、vfork和clone三個函數。這三個函數分別調用了sys_fork、sys_vfork、sys_clone,最終都調用了do_fork函數,差別在於參數的傳遞和一些基本的准備工作不同。可見這三者最終達到的最本質的目的都是創建一個新的進程。在這里需要明確一下,Linux內核中沒有獨立的「線程」結構,Linux的線程就是輕量級進程,換言之基本控制結構和Linux的進程是一樣的(都是通過struct task_struct管理)。
fork是最簡單的調用,不需要任何參數,僅僅是在創建一個子進程並為其創建一個獨立於父進程的空間。fork使用COW(寫時拷貝)機制,並且COW了父進程的棧空間。
vfork是一個過時的應用,vfork也是創建一個子進程,但是子進程共享父進程的空間。在vfork創建子進程之後,父進程阻塞,直到子進程執行了exec()或者exit()。vfork最初是因為fork沒有實現COW機制,而很多情況下fork之後會緊接著exec,而exec的執行相當於之前fork復制的空間全部變成了無用功,所以設計了vfork。而現在fork使用了COW機制,唯一的代價僅僅是復制父進程頁表的代價,所以vfork不應該出現在新的代碼之中。在Linux的manpage中隊vfork有這樣一段話:It is rather unfortunate that Linux revived this specter from the past. The BSD man page states: "This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of vfork() as it will, in that case, be made synonymous to fork(2)."
clone是Linux為創建線程設計的(雖然也可以用clone創建進程)。所以可以說clone是fork的升級版本,不僅可以創建進程或者線程,還可以指定創建新的命名空間(namespace)、有選擇的繼承父進程的內存、甚至可以將創建出來的進程變成父進程的兄弟進程等等。clone和fork的調用方式也很不相同,clone調用需要傳入一個函數,該函數在子進程中執行。此外,clone和fork最大不同在於clone不再復制父進程的棧空間,而是自己創建一個新的。
關於Linux命令的介紹,看看《linux就該這么學》,具體關於這一章地址3w(dot)linuxprobe/chapter-02(dot)html
❽ linux中fork,source和exec的區別
fork是系統調用,用來創建子進程。
source 讀取函數,讀取配置文件的時候用,不創建子進程,也是'.'
exec是創建進程,但是是創建的進程取代原來的進程,
所以fork是繼承皇位,exec是推翻皇朝;
比如安卓系統中:就是用exec進行rootfs切換的;因為他用的是busybox,所以真假rootfs之間的切換用exec的;
❾ linux下的fork()函數屬於內核函數還是C庫函數
如樓上所述,fork()是一個系統調用。
所有的線程或者進程處理函數都是系統調用,因為每種系統系統對進程或者線程的實現方式都不一定相同,C庫函數不可能做到預測到每種系統的實現方式。
❿ 純小白,請Linux怎麼調用fork()創建兩個子進程並運行
是的,需要在cpp裡面調用fork,然後再執行exec。
下面是個例子:
pid_t pid = fork();
if (pid < 0) {
return;
}
else if (pid == 0) {
printf("child process!!!!\n");
char *argv[] = { (char *)"tst_app", (char *)"xx", NULL };
execv("/usr/bin/tst_app", argv);
}
請採納,謝謝