A. 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中的同一個對象,這就是為什麼父子進程能通過其進行互相通信的原因。
B. 關於Linux的fork()
= OR ==
你初學者吧,請把賦值 =
和 == 值比較 搞清楚啊
= value assignment
== value compare
C. 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
D. linux fork: retry: 沒有子進程、資源暫時不可用問題解決
普通用戶執行命令時,有時候會報如下錯誤
是因為該用戶的線程滿了導致的。通過 ulimit -a 命令查看可以看到該用戶的 max user processes 值是1024或者4096。對比查看root用戶的,可以看到是unlimited。
知道問題出在哪兒,就好解決了。
解決方法1、直接使用 ulimit -u 命令修改即可。
解決方法2、通過修改配置文件中該參數的值即可。
centos7.5中配置文件為 /etc/security/limits.d/20-nproc.conf 。
網上的參考資料中centos6為 /etc/security/limits.d/90-nproc.conf 這個未驗證。
修改4096為10000(所需的值)保存即可。注意需要用戶重新登錄才能生效,這一步網上許多關於修改配置文件的解決方法後都沒提,要注意。
E. linux中fork,source和exec的區別
fork是系統調用,用來創建子進程。
source 讀取函數,讀取配置文件的時候用,不創建子進程,也是'.'
exec是創建進程,但是是創建的進程取代原來的進程,
所以fork是繼承皇位,exec是推翻皇朝;
比如安卓系統中:就是用exec進行rootfs切換的;因為他用的是busybox,所以真假rootfs之間的切換用exec的;
F. Linux應用程序中出現兩次fork的解釋
一個進程使用fork創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。
在一些程序中經常看見使用兩次fork創建子進程,原因如下:
以下摘自《UNIX環境高級編程》
如果一個進程fork一個子進程,但不要它等待子進程終止,也不希望子進程處於僵死狀態直到父進程終止,實現這一要求的技巧是調用fork兩次。程序如下:
#include
"apue.h"
#include
<sys/wait.h>
int
main(void)
{
G. 關於linux編程中fork()函數問題
第一次fork產生1個子進程,父進程的pid1為3411,子進程的pid1為0。此時已存在兩個進程。
這兩個進程分別執行pid2=fork()時,又產生兩個子進程,兩個子進程的pid2都為0;
原來兩個進程(第1次fork後)的pid2分別為兩個子進程的pid(3412,3413)
H. 請教linux下fork()創建子進程
pid = fork(); //創建進程命令點
if(pid < 0){...} //pid<0,表示fork出錯,程序一般會退出,不會出現pid=0和pid>0的情況
else if(0 == pid){...} //從這個點開始,程序出現分支 pid=0表示fork出來的子進程分支
else{....} //否則是原進程,即父進程
printf("here!"); //如果在上面兩個進程都沒有exit()操作時,執行完{}中的命令,都會走到這里
關於fork出來的父子進程關系,請仔細閱讀linux高級編程中進程一章節,內容很多,細細的閱讀並練習體會吧