新聞中心
🧸🧸🧸各位大佬大家好,我是豬皮兄弟🧸🧸🧸
- 一、重定向原理
- ①輸出重定向
- ②輸入重定向
- 二、重定向的系統(tǒng)調(diào)用dup2
- dup2輸出重定向
- 三、如何理解一切皆文件
- 四.緩沖區(qū)
- ①常見的緩沖區(qū)刷新策略
- ②緩沖區(qū)的認(rèn)識(shí)
因?yàn)槲募惖慕涌诙紩?huì)去調(diào)用系統(tǒng)調(diào)用,因?yàn)閷ξ募僮鲗儆谑俏募芾?,這部分內(nèi)容是需要操作系統(tǒng)去完成的,因此在系統(tǒng)中,他是只認(rèn)識(shí)fd這個(gè)數(shù)字的,并不知道FILE*這些,這些是上層封裝出來的
輸出重定向的本質(zhì)就是關(guān)掉stdout,也就是1號文件描述符,然后打開一個(gè)文件去占用這個(gè)文件描述符,然后輸出即可
int main()
{char buffer[SIZE]="zhupi";
close(1);//unistd.h
int fd = open("log.txt",O_WRONLY|O_TRUNC|O_CREAT,0666);
//打開文件,寫|覆蓋|沒有則創(chuàng)建,權(quán)限為0666,真實(shí)權(quán)限需要集合權(quán)限掩碼 0666&umask
if(fd<0) ...
printf("fd:%d\n",fd);
cout<
輸入重定向就是關(guān)掉stdin,也就是0號文件描述符,然后打開文件,占用0號文件描述符的位置,然后鍵盤輸入,或者其他輸入進(jìn)去即可
int main()
{char buffer[64];
close(0);
int fd = open("log.txt",O_RDONLY)
if(fd<0) ...
printf("fd:%d\n",fd);
fgets(buffer,sizeof buffer,stdin);
printf(buffer);
printf("\n");
close(fd);
return 0;
}
二、重定向的系統(tǒng)調(diào)用dup2int dup2(int oldfd,int newfd);
dup2的作用是把oldfd拷貝到newfd,比如給log.txt創(chuàng)建到3的位置,然后將3拷貝給1,所以3是oldfd,1是newfd(這只是dup2的做法,其實(shí)我們close掉1,再open文件log.txt也是一樣的效果)
int main(int argc,char*argv[])
{printf("%d\n",argc);
if(argc!=2)
{return 2;
}
int fd = open("log.txt",O_WROLNY|O_CREAT|O_TRUNC,0666);
if(fd<0)
{perror("open");
return 1;
}
dup2(fd,1);//old是fd,new是1,把fd拷貝給1
fprintf(stdout,"%s\n",argv[1]);
return 0;
}
當(dāng)我們自己先close(1),再open log.txt,最后如果close(fd)的時(shí)候,發(fā)現(xiàn)并沒有輸出進(jìn)log.txt,這是因?yàn)榫彌_區(qū)的原因,還沒有刷新進(jìn)log.txt就被關(guān)了,這個(gè)到后面緩沖區(qū)的時(shí)候再談,而dup2(fd,1)就不會(huì),這是dup2的一種特性
三、如何理解一切皆文件一切皆文件時(shí)Linux的設(shè)計(jì)哲學(xué),體現(xiàn)在軟件設(shè)計(jì)層面
那Linux是C寫的,如何用C實(shí)現(xiàn)面向?qū)ο?,甚至是運(yùn)行時(shí)多態(tài)?
也就是用結(jié)構(gòu)體來體現(xiàn)類的成員變量,然后存函數(shù)指針來找成員函數(shù)
所以說底層不同的硬件,對應(yīng)不同的操作方法就可以了,每個(gè)設(shè)備實(shí)現(xiàn)的read和write不同
所以設(shè)計(jì)了一個(gè)struct_file來描述,在上層沒有任何的硬件差別,看待所有文件的格式,都統(tǒng)一成了對file_struct的操作,所以在操作系統(tǒng)之上,Linux就有一切皆文件,Linux的這種管理模式,稱作VFS(virtual file system虛擬文件系統(tǒng))
1.立即刷新
2.行刷新(行緩沖)
3,滿刷新(全緩沖)
一般而言,行緩沖的設(shè)備一般是顯示器
因?yàn)轱@示器是給用戶看的,一方面照顧效率,一方面照顧用戶體驗(yàn)
全緩沖的設(shè)備一般是磁盤文件
因?yàn)樗⑿碌酱疟P文件,因?yàn)橛脩羰遣恍枰R上看到的,更在乎的是效率
但是所有的設(shè)備,都傾向于全緩沖,因?yàn)榫彌_區(qū)滿了才刷新就意味著需要更少的IO操作->更少的訪問外設(shè),提高效率,其他屬性層略是結(jié)合具體情況做的妥協(xié)(都傾向于緩沖區(qū))
例:
因?yàn)橄蝻@示器打印是行緩沖,所以都能夠正常打印,但當(dāng)向文件中打印的時(shí)候,因?yàn)樗⑿虏呗允侨彌_(滿刷新),所以在程序結(jié)束之前或者說緩沖區(qū)滿之前并不會(huì)刷新到文件,所以子進(jìn)程進(jìn)行對父進(jìn)程的拷貝,所以C的打印接口打印了兩次,那么write系統(tǒng)調(diào)用為什么只打印一次呢?因?yàn)榫彌_區(qū)是C標(biāo)準(zhǔn)庫提供的,緩沖區(qū)并不是OS的,所以系統(tǒng)調(diào)用并不會(huì)用這套緩沖區(qū)的刷新策略,而且,父子進(jìn)程所指向的緩沖區(qū)在打印之前也是指向的同一個(gè),因?yàn)橛袑憰r(shí)拷貝。(C的打印接口其實(shí)就是拷貝一份給緩沖區(qū),然后緩沖區(qū)去調(diào)用系統(tǒng)調(diào)來刷新)
上面我們指的緩沖區(qū)是用戶級緩沖區(qū),這個(gè)緩沖區(qū)是C標(biāo)準(zhǔn)庫提供的,除此之外,還有內(nèi)核級緩沖區(qū),其實(shí)調(diào)用write,也不是直接寫到外設(shè)上的,而是每個(gè)file結(jié)構(gòu)體都有對應(yīng)的內(nèi)核緩沖區(qū)。
需要注意的是:
1.我們需要避免在全緩沖策略下在還未刷新數(shù)據(jù)前關(guān)閉文件描述符導(dǎo)致數(shù)據(jù)并未刷新
2.通過關(guān)閉1號文件描述符,再讓打開的文件取占位,就可以達(dá)到行刷新的目的
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
新聞標(biāo)題:Linux重定向原理與系統(tǒng)調(diào)用dup2-創(chuàng)新互聯(lián)
文章起源:http://www.dlmjj.cn/article/cchcde.html