?? unix
字號:
Unit)的時間,包括:用戶時<BR>
間,系統(tǒng)時間,用戶各子進(jìn)程合計時間,系統(tǒng)各子進(jìn)程合計時間)<BR><BR>
* 資源使用(resource
utilizations)設(shè)定為0<BR><BR> *
阻塞信號集初始化為空集(譯者注:原文此處不明確,譯文根據(jù)fork函數(shù)手冊頁<BR>
稍做修改)<BR><BR> *
不繼承由timer_create函數(shù)創(chuàng)建的計時器<BR><BR> *
不繼承異步輸入和輸出<BR><BR>1.1.2 fork函數(shù) 與
vfork函數(shù)的區(qū)別在哪里里?<BR>-------------------------------------------<BR><BR>有些系統(tǒng)有一個系統(tǒng)調(diào)用‘vfork()’,它最初被設(shè)計成‘fork()’的較少額外支出<BR>(lower-overhead)版本。因為‘fork()’包括拷貝整個進(jìn)程的地址空間,所以非常<BR>“昂貴”,這個‘vfork()’函數(shù)因此被引入。(在3.0BSD中)(譯者注:BSD:<BR>Berkeley
Software
Distribution)<BR><BR>*但是*,自從‘vfork()’被引入,‘fork()’的實現(xiàn)方法得到了很大改善,最值得<BR>注意的是“寫操作時拷貝”(copy-on-write)的引入,它是通過允許父子進(jìn)程可訪問<BR>相同物理內(nèi)存從而偽裝(fake)了對進(jìn)程地址空間的真實拷貝,直到有進(jìn)程改變內(nèi)<BR>存中數(shù)據(jù)時才拷貝。這個提高很大程度上抹殺了需要‘vfork()’的理由;事實上,<BR>一大部份系統(tǒng)完全喪失了‘vfork()’的原始功能。但為了兼容,它們?nèi)匀惶峁?lt;BR>‘vfork()’函數(shù)調(diào)用,但它只是簡單地調(diào)用‘fork()’,而不試圖模擬所有‘vfork()’<BR>的語義(semantics,
譯文取自<<高級編程>>,指定義的內(nèi)容和做法)。<BR><BR>結(jié)論是,試圖使用任何‘fork()’和‘vfork()’的不同點是*很*不明智的。事實上,<BR>可能使用‘vfork()’根本就是不明智的,除非你確切知道你想*干什么*。<BR><BR>兩者的基本區(qū)別在于當(dāng)使用‘vfork()’創(chuàng)建新進(jìn)程時,父進(jìn)程將被暫時阻塞,而<BR>子進(jìn)程則可以借用父進(jìn)程的地址空間。這個奇特狀態(tài)將持續(xù)直到子進(jìn)程要么退<BR>出,要么調(diào)用‘execve()’,至此父進(jìn)程才繼續(xù)執(zhí)行。<BR><BR>這意味著一個由‘vfork()’創(chuàng)建的子進(jìn)程必須小心以免出乎意料地改變父進(jìn)程的<BR>變量。特別的,子進(jìn)程必須不從包含‘vfork()’調(diào)用的函數(shù)返回,而且必須不調(diào)<BR>用‘exit()’(如果它需要退出,它需要使用‘_exit()’;事實上,對于使用正常<BR>‘fork()’創(chuàng)建的子進(jìn)程這也是正確的)(譯者注:參見1.1.3)<BR><BR>1.1.3
為何在一個fork的子進(jìn)程分支中使用_exit函數(shù)而不使用exit函數(shù)?<BR>-----------------------------------------------------------------<BR><BR>‘exit()’與‘_exit()’有不少區(qū)別在使用‘fork()’,特別是‘vfork()’時變得很<BR>突出。<BR><BR>‘exit()’與‘_exit()’的基本區(qū)別在于前一個調(diào)用實施與調(diào)用庫里用戶狀態(tài)結(jié)構(gòu)<BR>(user-mode
constructs)有關(guān)的清除工作(clean-up),而且調(diào)用用戶自定義的清除程序<BR>(譯者注:自定義清除程序由atexit函數(shù)定義,可定義多次,并以倒序執(zhí)行),相對<BR>應(yīng),后一個函數(shù)只為進(jìn)程實施內(nèi)核清除工作。<BR><BR>在由‘fork()’創(chuàng)建的子進(jìn)程分支里,正常情況下使用‘exit()’是不正確的,這是<BR>因為使用它會導(dǎo)致標(biāo)準(zhǔn)輸入輸出(譯者注:stdio:
Standard Input
Output)的緩沖區(qū)被<BR>清空兩次,而且臨時文件被出乎意料的刪除(譯者注:臨時文件由tmpfile函數(shù)創(chuàng)建<BR>在系統(tǒng)臨時目錄下,文件名由系統(tǒng)隨機(jī)生成)。在C++程序中情況會更糟,因為靜<BR>態(tài)目標(biāo)(static
objects)的析構(gòu)函數(shù)(destructors)可以被錯誤地執(zhí)行。(還有一些特殊情<BR>況,比如守護(hù)程序,它們的*父進(jìn)程*需要調(diào)用‘_exit()’而不是子進(jìn)程;適用于絕<BR>大多數(shù)情況的基本規(guī)則是,‘exit()’在每一次進(jìn)入‘main’函數(shù)后只調(diào)用一次。)<BR><BR>在由‘vfork()’創(chuàng)建的子進(jìn)程分支里,‘exit()’的使用將更加危險,因為它將影響<BR>*父*進(jìn)程的狀態(tài)。<BR><BR>1.2
環(huán)境變量<BR>============<BR><BR>1.2.1 如何從程序中獲得/設(shè)置環(huán)境變量?<BR>--------------------------------------<BR>獲得一個環(huán)境變量可以通過調(diào)用‘getenv()’函數(shù)完成。<BR><BR>
#include
<stdlib.h><BR><BR>
char *getenv(const char
*name);<BR><BR>設(shè)置一個環(huán)境變量可以通過調(diào)用‘putenv()’函數(shù)完成。<BR><BR>
#include
<stdlib.h><BR><BR>
int putenv(char
*string);<BR><BR>變量string應(yīng)該遵守"name=value"的格式。已經(jīng)傳遞給putenv函數(shù)的字符串*不*能夠被<BR>釋放或變成無效,因為一個指向它的指針將由‘putenv()’保存。這意味著它必須是<BR>在靜態(tài)數(shù)據(jù)區(qū)中或是從堆(heap)分配的。如果這個環(huán)境變量被另一個‘putenv()’的<BR>調(diào)用重新定義或刪除,上述字符串可以被釋放。<BR><BR>/*
譯者增加:<BR><BR>因為putenv()有這樣的局限,在使用中經(jīng)常會導(dǎo)致一些錯<BR>誤,GNU
libc 中還包括了兩個BSD風(fēng)格的函數(shù):<BR>#include
<stdlib.h><BR>int setenv(const char *name,
const char *value, int replace);<BR>void
unsetenv(const char
*name);<BR><BR>setenv()/unsetenv()函數(shù)可以完成所有putenv()能做的事。setenv()
可以不受指針<BR>限制地向環(huán)境變量中添加新值,但傳入?yún)?shù)不能為空(NULL)。當(dāng)replace為0時,如<BR>果環(huán)境變量中已經(jīng)有了name項,函數(shù)什么也不做(保留原項),否則原項被覆蓋。<BR>unsetenv()是用來把name項從環(huán)境變量中刪除。注意:這兩個函數(shù)只存在在BSD和GNU<BR>庫中,其他如SunOS系統(tǒng)中不包括它們,因此將會帶來一些兼容問題。我們可以用<BR>getenv()/putenv()來實現(xiàn):<BR><BR>int
setenv(const char *name, const char
*value, int replace)<BR>{<BR> char
*envstr;<BR><BR> if (name == NULL ||
value ==
NULL)<BR> return
1;<BR> if (getenv(name)
!=NULL)<BR>
{<BR> envstr
= (char *) malloc(strlen(name) + strlen(value) +
2);<BR> sprintf
(envstr, "%s=%s", name,
value);<BR> if
(putenv(envstr));<BR>
return 1;<BR>
}<BR> return
0;<BR>}<BR>*/<BR><BR>記住環(huán)境變量是被繼承的;每一個進(jìn)程有一個不同的環(huán)境變量表拷貝(譯者注:<BR>從core文件中我們可以看出這一點)。結(jié)果是,你不能從一個其他進(jìn)程改變當(dāng)前<BR>進(jìn)程的環(huán)境變量,比如shell進(jìn)程。<BR><BR>假設(shè)你想得到環(huán)境變量‘TERM’的值,你需要使用下面的程序:<BR><BR>
char *envvar;<BR><BR>
envvar=getenv("TERM");<BR><BR>
printf("The value for the environment variable
TERM is ");<BR>
if(envvar)<BR>
{<BR>
printf("%s\n",envvar);<BR>
}<BR>
else<BR>
{<BR>
printf("not set.\n");<BR>
}<BR><BR>現(xiàn)在假設(shè)你想創(chuàng)建一個新的環(huán)境變量,變量名為‘MYVAR’,值為‘MYVAL’。<BR>以下是你將怎樣做:<BR><BR>
static char
envbuf[256];<BR><BR>
sprintf(envbuf,"MYVAR=%s","MYVAL");<BR><BR>
if(putenv(envbuf))<BR>
{<BR>
printf("Sorry, putenv() couldn't find the memory
for
%s\n",envbuf);<BR>
/* Might exit() or something here if you can't
live without it */<BR>
}<BR><BR>1.2.2
我怎樣讀取整個環(huán)境變量表?<BR>--------------------------------<BR><BR>如果你不知道確切你想要的環(huán)境變量的名字,那么‘getenv()’函數(shù)不是很有用。<BR>在這種情況下,你必須更深入了解環(huán)境變量表的存儲方式。<BR><BR>全局變量,‘char
**envrion’,包含指向環(huán)境字符串指針數(shù)組的指針,每一個字<BR>符串的形式為‘“NAME=value”’(譯者注:和putenv()中的“string”的格式相同)。<BR>這個數(shù)組以一個‘空’(NULL)指針標(biāo)記結(jié)束。這里是一個打印當(dāng)前環(huán)境變量列表<BR>的小程序(類似‘printenv’)。<BR><BR>
#include
<stdio.h><BR><BR>
extern char
**environ;<BR><BR> int
main()<BR>
{<BR>
char **ep =
environ;<BR>
char
*p;<BR>
while ((p =
*ep++))<BR>
printf("%s\n",
p);<BR>
return 0;<BR>
}<BR><BR>一般情況下,‘envrion’變量作為可選的第三個參數(shù)傳遞給‘main()’;就是說,<BR>上面的程序可以寫成:<BR><BR>
#include
<stdio.h><BR><BR>
int main(int argc, char **argv, char
**envp)<BR>
{<BR>
char
*p;<BR>
while ((p =
*envp++))<BR>
printf("%s\n",
p);<BR>
return 0;<BR>
}<BR><BR>雖然這種方法被廣泛的操縱系統(tǒng)所支持(譯者注:包括DOS),這種方法事實上并<BR>沒有被POSIX(譯者注:POSIX:
Portable Operating System
Interace)標(biāo)準(zhǔn)所定義。(一<BR>般的,它也比較沒用)<BR><BR>1.3
我怎樣睡眠小于一秒?<BR>========================<BR><BR>在所有Unix中都有的‘sleep()’函數(shù)只允許以秒計算的時間間隔。如果你想要更<BR>細(xì)化,那么你需要尋找替換方法:<BR><BR>
* 許多系統(tǒng)有一個‘usleep()’函數(shù)<BR><BR> *
你可以使用‘select()’或‘poll()’,并設(shè)置成無文件描述符并試驗;一個普<BR>
遍技巧是基于其中一個函數(shù)寫一個‘usleep()’函數(shù)。(參見comp.unix.questions<BR>
FAQ 的一些例子)<BR><BR> *
如果你的系統(tǒng)有itimers(很多是有的)(譯者注:setitimer和getitimer是兩個操作<BR>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -