forklinux等
❶ linux應用程序中出現兩次fork的解釋
一個進程使用fork創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。
在一些程序中經常看見使用兩次fork創建子進程,原因如下:
以下摘自《UNIX環境高級編程》
如果一個進程fork一個子進程,但不要它等待子進程終止,也不希望子進程處於僵死狀態直到父進程終止,實現這一要求的技巧是調用fork兩次。程序如下:
#include
"apue.h"
#include
<sys/wait.h>
int
main(void)
{
❷ 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函數
不止三個,子進程仍然在循環體內,所以子進程也會根據它的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,source和exec的區別
exec和source都屬於bash內部命令(builtins commands),在bash下輸入man exec或man source可以查看所有的內部命令信息。
bash shell的命令分為兩類:外部命令和內部命令。外部命令是通過系統調用或獨立的程序實現的,如sed、awk等等。內部命令是由特殊的文件格式(.def)所實現,如cd、history、exec等等。
在說明exec和source的區別之前,先說明一下fork的概念。
fork是linux的系統調用,用來創建子進程(child process)。子進程是父進程(parent process)的一個副本,從父進程那裡獲得一定的資源分配以及繼承父進程的環境。子進程與父進程唯一不同的地方在於pid(process id)。
環境變數(傳給子進程的變數,遺傳性是本地變數和環境變數的根本區別)只能單向從父進程傳給子進程襲臘。不管子進程的環境變數如何變化,都不會影響父進程的環境變數。
shell script:
有兩種方法執行shell scripts,一種是新產生一個shell,然後執行相應的shell scripts;一種是在當前shell下執行,不再啟用其他shell。
新產生一個shell然後再執行scripts的方法是在scripts文件開頭加入以下語句
#!/bin/sh
一般的script文件(.sh)即是這種用法。這種方法先啟用新的sub-shell(新的子進程),然後在其下執行命令。
另外一種方法就是上面說過的source命令,不再產生新的shell,而在當前shell下執行一切命令。
source:
source命令即點(.)命令。
在bash下輸入man source,找到source命拍沒滑令解釋處,可以看到解釋"Read and execute commands from filename in the current shell environment and ..."。從中可以知道,source命令是在當前進程中執行參數文件中的各個命令,而不是察銀另起子進程(或sub-shell)。source filename or .filename 執行filename中的命令。
exec:
在bash下輸入man exec,找到exec命令解釋處,可以看到有"No new process is created."這樣的解釋,這就是說exec命令不產生新的子進程。那麼exec與source的區別是什麼呢?
exec命令在執行時會把當前的shell process關閉,然後換到後面的命令繼續執行。
======================================================================================================================
下面我們寫個腳本來測試一下,這樣你就會很容易的讀懂我上面所說的東西~
1.sh
#!/bin/bashA=Becho"PIDfor1.shbeforeexec/source/fork:
"exportAecho"1.sh:$Ais$A"case$1inexec)echo"usingexec..."exec./2.sh;;source)echo"usingsource..."../2.sh;;∗)echo"usingforkbydefault..."./2.sh;;esacecho"PIDfor1.shafterexec/source/fork:
"echo"1.sh:$Ais$A"
2.sh
#!/bin/bash
echo"PIDfor2.sh:$$"
echo"2.shget$A=$Afrom1.sh"
A=C
exportA
echo"2.sh:$Ais$A"
=================》》》》》》》》》》》
測試結果:
[root@node2 ~]$ ./1.sh fork
PID for 1.sh before exec/source/fork:10175
1.sh: $A is B
using fork by default...
PID for 2.sh:10176
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:10175
1.sh: $A is B
=============================================
[root@node2 ~]$ ./1.sh source
PID for 1.sh before exec/source/fork:10185
1.sh: $A is B
using source...
PID for 2.sh:10185
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:10185
1.sh: $A is C
=============================================
[root@node2 ~]$ ./1.sh exec
PID for 1.sh before exec/source/fork:10194
1.sh: $A is B
using exec...
PID for 2.sh:10194
2.sh get $A=B from 1.sh
2.sh: $A is C
[cpsuser@cps-svr-153 zy]$
=============================================
從以上結果可以看出:
1.執行source和exec的過程中沒有產生新的進程,而fork是默認的運行方式,在運行的過程中會產生新的進程,也就是子進程
2.source和exec的區別在於exec執行完畢後沒有輸出進程,也就是說運行完畢2.sh後直接退出了,沒有返回1.sh
3.fork和source的最後一句輸出分別為:1.sh: $A is B (fork,說明它運行的環境不一樣,要不然輸出的應該是C)
1.sh: $A is C(source,說明從始至終都是在一個shell中執行)
小節:
source 指定腳本中的命令在同一個shell中運行。(默認shell中的命令都是創建sub-shell,然後執行。執行完後,返回父shell)
fork 就是創建sub-shell運行腳本中的命令,和默認運行方式相同。
exec 和source相似,區別就是,運行完畢命令後退出,不會返回父shell
❻ linux下的fork()運用
fork()創建一個子進程,fork()進入內核,調用一次返回兩次,如果返回的pid == 0子進程先返回,如果pid > 0(此時返回的是子進程的pid),父進程先返回。至於子進程和父進程哪個先返回,要看內核的調度演算法。輸出次序亂序,都有可能。父進程和子進程是並發執行的。
❼ 關於Linux的fork()
= OR ==
你初學者吧,請把賦值 =
和 == 值比較 搞清楚啊
= value assignment
== value compare