日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
利用管道在Linux中讀取數(shù)據(jù),高效簡(jiǎn)便的方法(linux從管道中讀取數(shù)據(jù))

在Linux系統(tǒng)中,管道是一種非常實(shí)用的工具,可以使不同進(jìn)程之間相互通信和傳遞數(shù)據(jù)。通過使用管道,可以在不破壞原有程序結(jié)構(gòu)的情況下,輕松地實(shí)現(xiàn)數(shù)據(jù)的傳輸和處理。本文將介紹如何利用管道在Linux中讀取數(shù)據(jù),并詳細(xì)講解其高效簡(jiǎn)便的方法。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括涇川網(wǎng)站建設(shè)、涇川網(wǎng)站制作、涇川網(wǎng)頁制作以及涇川網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,涇川網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到?jīng)艽ㄊ》莸牟糠殖鞘?,未來相信?huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

一、什么是管道?

在Linux系統(tǒng)中,管道是一個(gè)特殊的文件,可以實(shí)現(xiàn)進(jìn)程之間的數(shù)據(jù)傳輸。管道的本質(zhì)是一種文件緩沖區(qū),其大小一般為4KB。在使用管道時(shí),數(shù)據(jù)會(huì)被傳遞到緩沖區(qū)中,并從另一端讀取。管道的使用方式有兩種:匿名管道和命名管道。

匿名管道是最常用的一種管道,它是由操作系統(tǒng)自動(dòng)創(chuàng)建的,無需指定名稱,只能實(shí)現(xiàn)單向通信,且只能在父子進(jìn)程或兄弟進(jìn)程之間使用。命名管道是一種具有名稱的管道,需要使用mkfifo命令創(chuàng)建,可以實(shí)現(xiàn)多種進(jìn)程之間的雙向通信。在本文中,我們將重點(diǎn)介紹匿名管道的使用。

二、使用管道讀取數(shù)據(jù)的方法

在Linux系統(tǒng)中,使用管道讀取數(shù)據(jù)可以分為兩個(gè)步驟:創(chuàng)建管道,讀取數(shù)據(jù)。

創(chuàng)建匿名管道需要使用pipe函數(shù)。其函數(shù)原型如下:

“`c

#include

int pipe(int pipefd[2]);

“`

其中,pipefd表示管道的文件描述符,是一個(gè)長(zhǎng)度為2的一維數(shù)組,其中pipefd[0]表示讀管道,pipefd[1]表示寫管道。在執(zhí)行pipe函數(shù)時(shí),操作系統(tǒng)會(huì)自動(dòng)分配讀寫管道。

接下來,通過fork函數(shù)創(chuàng)建子進(jìn)程,并使用dup2函數(shù)將父進(jìn)程的標(biāo)準(zhǔn)輸出重定向至寫管道,子進(jìn)程的標(biāo)準(zhǔn)輸入重定向至讀管道。這樣,父進(jìn)程就可以將數(shù)據(jù)寫入標(biāo)準(zhǔn)輸出,而子進(jìn)程可以從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的傳輸。

以下是一個(gè)使用管道讀取數(shù)據(jù)的示例代碼:

“`c

#include

#include

#include

#include

int mn()

{

int pipefd[2];

pid_t pid;

char buf[1024];

if (pipe(pipefd) == -1) {

perror(“pipe”);

exit(EXIT_FLURE);

}

pid = fork();

if (pid == -1) {

perror(“fork”);

exit(EXIT_FLURE);

} else if (pid == 0) { // 子進(jìn)程

close(pipefd[1]); // 關(guān)閉寫管道

// 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)

if (read(pipefd[0], buf, 1024) == -1) {

perror(“read”);

exit(EXIT_FLURE);

}

printf(“child process received: %s\n”, buf);

close(pipefd[0]);

_exit(EXIT_SUCCESS);

} else { // 父進(jìn)程

close(pipefd[0]); // 關(guān)閉讀管道

// 將數(shù)據(jù)寫入標(biāo)準(zhǔn)輸出

if (write(pipefd[1], “hello world”, 12) == -1) {

perror(“write”);

exit(EXIT_FLURE);

}

close(pipefd[1]);

wt(NULL);

exit(EXIT_SUCCESS);

}

return 0;

}

“`

在該示例代碼中,首先創(chuàng)建了一個(gè)長(zhǎng)度為2的一維數(shù)組pipefd,用于存放管道的文件描述符,然后使用pipe函數(shù)創(chuàng)建管道。接著,使用fork函數(shù)創(chuàng)建子進(jìn)程,在子進(jìn)程中將讀管道改為標(biāo)準(zhǔn)輸入,并通過read函數(shù)從管道中讀取數(shù)據(jù)。在父進(jìn)程中,將寫管道改為標(biāo)準(zhǔn)輸出,并通過write函數(shù)將數(shù)據(jù)寫入管道。在使用管道完成數(shù)據(jù)傳輸后,需要及時(shí)關(guān)閉管道以釋放資源。

三、管道的高效簡(jiǎn)便使用方法

在實(shí)際開發(fā)中,為了簡(jiǎn)化代碼和提高效率,可以采用一些高效簡(jiǎn)便的使用方法。

1.利用重定向?qū)崿F(xiàn)管道的創(chuàng)建

在前面的示例代碼中,我們使用pipe函數(shù)來創(chuàng)建管道。然而,通過重定向也可以實(shí)現(xiàn)同樣的功能。例如,下面的命令就可以創(chuàng)建一個(gè)管道,將標(biāo)準(zhǔn)輸出重定向至管道的寫端:

“`shell

$ ls / | sort | less

“`

在上述命令中,ls命令將其標(biāo)準(zhǔn)輸出重定向至管道的寫端,sort命令從管道中讀取數(shù)據(jù)進(jìn)行排序,最后將排序結(jié)果通過less命令輸出。

2.利用xargs命令實(shí)現(xiàn)管道數(shù)據(jù)的分割

在使用管道讀取數(shù)據(jù)時(shí),有時(shí)需要將管道的數(shù)據(jù)進(jìn)行分割。在Linux中,可以使用xargs命令來實(shí)現(xiàn)這一功能。xargs命令將管道數(shù)據(jù)按照指定的分隔符進(jìn)行分割,并調(diào)用另一個(gè)命令對(duì)每個(gè)分割數(shù)據(jù)進(jìn)行處理。

例如,下面的命令可以將根目錄下的文件名按照空格進(jìn)行分割:

“`shell

$ ls -1 / | xargs -n1

“`

在上述命令中,-n1參數(shù)表示將每個(gè)文件名都當(dāng)作一個(gè)參數(shù)傳遞給后面的命令。

3.利用tee命令實(shí)現(xiàn)管道數(shù)據(jù)的復(fù)制

在使用管道進(jìn)行數(shù)據(jù)處理時(shí),有時(shí)需要將管道的數(shù)據(jù)復(fù)制到多個(gè)命令中進(jìn)行處理。在Linux中,可以使用tee命令來實(shí)現(xiàn)這一功能。tee命令可以將管道數(shù)據(jù)復(fù)制到指定的文件中,并同樣輸出到標(biāo)準(zhǔn)輸出。

例如,下面的命令可以將根目錄下的文件名按照空格進(jìn)行分割,并將結(jié)果輸出到文件和標(biāo)準(zhǔn)輸出中:

“`shell

$ ls -1 / | tee output.txt

“`

在上述命令中,output.txt表示需要將數(shù)據(jù)輸出的文件名。

結(jié)語

相關(guān)問題拓展閱讀:

  • linux環(huán)境下,c語言怎么讀取WEB服務(wù)器的80端口上頁面的內(nèi)容
  • Handler消息機(jī)制(一):Linux的epoll機(jī)制

linux環(huán)境下,c語言怎么讀取WEB服務(wù)器的80端口上頁面的內(nèi)容

已知url ,host, port;

int s, size;

struct sockaddr_in sin;

struct hostent* phe;

char cmd;

char msg_hdr;

char* p;

//準(zhǔn)備http中GET 方法的請(qǐng)求。

sprintf(cmd,”GET %s\r\nHTTP/1.1\r\nHost:%s”, url, host);

//創(chuàng)建socket

if((s=socket(PF_INET,SOCK_STREAM,0))h_addr,sizeof(struct in_addr));

sin.sin_family=AF_INET;

sin.sin_port=htons(pms->port);

//跟遠(yuǎn)程機(jī)器建立連接,失敗函數(shù)返回-1

if(connect(s,(struct sockaddr*)&sin,sizeof(sin))==-1)

return -1;

//發(fā)送GET請(qǐng)求

if(write(s,cmd,strlen(cmd))h_addr,sizeof(struct in_addr));

sin.sin_family=AF_INET;

sin.sin_port=htons(port);

//建立連接

if(connect(s,(struct sockaddr*)&sin,sizeof(sin))==-1)

return 0;

//發(fā)送讀取請(qǐng)求

if(write(s,cmd,strlen(cmd))

error;

Handler消息機(jī)制(一):Linux的epoll機(jī)制

在linux 沒有實(shí)現(xiàn)epoll事件驅(qū)動(dòng)機(jī)制之前,我們一般選擇用select或者poll等IO多路復(fù)用的方法來實(shí)現(xiàn)并發(fā)服務(wù)程序。在linux新的內(nèi)核中,有了一種替換它的機(jī)制,就是epoll。

相比select模型,

poll使用鏈表保存文件描述符,因此沒有了監(jiān)視文件數(shù)量的限制

,但其稿鬧他三個(gè)缺點(diǎn)依然存在。

假設(shè)我們的服務(wù)器需要支持100萬的并發(fā)連接,則在__FD_SETSIZE 為1024的情況下兆敬答,則我們至少需要開辟1k個(gè)進(jìn)程才能實(shí)現(xiàn)100萬的并發(fā)連接。除了進(jìn)程間上下文切換的時(shí)間消耗外,從內(nèi)核/用戶空間大量的無腦內(nèi)存拷貝、數(shù)組輪詢等,是系統(tǒng)難以承受的。因此,基于select模型的服務(wù)器程序,要達(dá)到10萬級(jí)別的并發(fā)訪問,是一個(gè)很難完成的任務(wù)。

由于epoll的實(shí)現(xiàn)機(jī)制與select/poll機(jī)制完全不同,上面所說的 select的缺點(diǎn)在epoll上不復(fù)存在。

設(shè)想一下如下場(chǎng)景:有100萬個(gè)客戶端同時(shí)與一個(gè)服務(wù)器進(jìn)程保持著TCP連接。而每一時(shí)刻,通常只有幾百上千個(gè)TCP連接是活躍的(事實(shí)上大部分場(chǎng)景都是這種情況)。如何實(shí)現(xiàn)這樣的高并發(fā)?

在select/poll時(shí)代,服務(wù)器進(jìn)程每次都把這100萬個(gè)連接告訴操作系統(tǒng)(從用戶態(tài)復(fù)制句柄數(shù)據(jù)結(jié)構(gòu)到內(nèi)核態(tài)),讓操作系統(tǒng)內(nèi)核去查詢這些套接字上是否有事件發(fā)生,輪詢完后,再將句柄數(shù)據(jù)復(fù)制到用戶態(tài),讓服務(wù)器應(yīng)用程序輪詢處理已發(fā)生的網(wǎng)絡(luò)事件,這一過程資源消耗較大,因此,select/poll一般只能處理幾千的并發(fā)連接。

epoll的設(shè)計(jì)和實(shí)現(xiàn)與select完全不同。epoll通過在Linux內(nèi)核中申請(qǐng)一個(gè)簡(jiǎn)易的文件系統(tǒng)(文件系統(tǒng)一般用什么數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)?B+樹)。把原先的select/poll調(diào)用分成了3個(gè)部分:

1)調(diào)用epoll_create()建立一個(gè)epoll對(duì)象(在epoll文件系統(tǒng)中為這個(gè)句柄對(duì)象分配資族慧源)

2)調(diào)用epoll_ctl向epoll對(duì)象中添加這100萬個(gè)連接的套接字

3)調(diào)用epoll_wait收集發(fā)生的事件的連接

如此一來,要實(shí)現(xiàn)上面說是的場(chǎng)景,只需要在進(jìn)程啟動(dòng)時(shí)建立一個(gè)epoll對(duì)象,然后在需要的時(shí)候向這個(gè)epoll對(duì)象中添加或者刪除連接。同時(shí),epoll_wait的效率也非常高,因?yàn)檎{(diào)用epoll_wait時(shí),并沒有一股腦的向操作系統(tǒng)復(fù)制這100萬個(gè)連接的句柄數(shù)據(jù),內(nèi)核也不需要去遍歷全部的連接。

當(dāng)某一進(jìn)程調(diào)用epoll_create方法時(shí),Linux內(nèi)核會(huì)創(chuàng)建一個(gè)eventpoll結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體中有兩個(gè)成員與epoll的使用方式密切相關(guān)。eventpoll結(jié)構(gòu)體如下所示:

每一個(gè)epoll對(duì)象都有一個(gè)獨(dú)立的eventpoll結(jié)構(gòu)體,用于存放通過epoll_ctl方法向epoll對(duì)象中添加進(jìn)來的事件。這些事件都會(huì)掛載在紅黑樹中,如此,重復(fù)添加的事件就可以通過紅黑樹而高效的識(shí)別出來(紅黑樹的插入時(shí)間效率是lgn,其中n為樹的高度)。

而所有

添加到epoll中的事件都會(huì)與設(shè)備(網(wǎng)卡)驅(qū)動(dòng)程序建立回調(diào)關(guān)系,也就是說,當(dāng)相應(yīng)的事件發(fā)生時(shí)會(huì)調(diào)用這個(gè)回調(diào)方法

。這個(gè)回調(diào)方法在內(nèi)核中叫ep_poll_callback,它會(huì)將發(fā)生的事件添加到rdlist雙鏈表中。

在epoll中,對(duì)于每一個(gè)事件,都會(huì)建立一個(gè)epitem結(jié)構(gòu)體,如下所示:

當(dāng)調(diào)用epoll_wait檢查是否有事件發(fā)生時(shí),只需要檢查eventpoll對(duì)象中的rdlist雙鏈表中是否有epitem元素即可。如果rdlist不為空,則把發(fā)生的事件復(fù)制到用戶態(tài),同時(shí)將事件數(shù)量返回給用戶。

epoll結(jié)構(gòu)示意圖

通過紅黑樹和雙鏈表數(shù)據(jù)結(jié)構(gòu),并結(jié)合回調(diào)機(jī)制,造就了epoll的高效。

events可以是以下幾個(gè)宏的:

EPOLLIN:觸發(fā)該事件,表示對(duì)應(yīng)的文件描述符上有可讀數(shù)據(jù)。(包括對(duì)端SOCKET正常關(guān)閉);

EPOLLOUT:觸發(fā)該事件,表示對(duì)應(yīng)的文件描述符上可以寫數(shù)據(jù);

EPOLLPRI:表示對(duì)應(yīng)的文件描述符有緊急的數(shù)據(jù)可讀(這里應(yīng)該表示有帶外數(shù)據(jù)到來);

EPOLLERR:表示對(duì)應(yīng)的文件描述符發(fā)生錯(cuò)誤;

EPOLLHUP: 表示對(duì)應(yīng)的文件描述符被掛斷;

EPOLLET:將EPOLL設(shè)為邊緣觸發(fā)(EdgeTriggered)模式,這是相對(duì)于水平觸發(fā)(Level Triggered)來說的。

EPOLLONESHOT: 只監(jiān)聽一次事件,當(dāng)監(jiān)聽完這次事件之后,如果還需要繼續(xù)監(jiān)聽這個(gè)socket的話,需要再次把這個(gè)socket加入到EPOLL隊(duì)列里。

示例:

ET(EdgeTriggered)

:高速工作模式,只支持no_block(非阻塞模式)。在此模式下,當(dāng)描述符從未就緒變?yōu)榫途w時(shí),內(nèi)核通過epoll告知。然后它會(huì)假設(shè)用戶知道文件描述符已經(jīng)就緒,并且不會(huì)再為那個(gè)文件描述符發(fā)送更多的就緒通知,直到某些操作導(dǎo)致那個(gè)文件描述符不再為就緒狀態(tài)了。(觸發(fā)模式只在數(shù)據(jù)就緒時(shí)通知一次,若數(shù)據(jù)沒有讀完,下一次不會(huì)通知,直到有新的就緒數(shù)據(jù))

LT(LevelTriggered)

:缺省工作方式,支持blocksocket和no_blocksocket。在LT模式下內(nèi)核會(huì)告知一個(gè)文件描述符是否就緒了,然后可以對(duì)這個(gè)就緒的fd進(jìn)行IO操作。如果不作任何操作,內(nèi)核還是會(huì)繼續(xù)通知!若數(shù)據(jù)沒有讀完,內(nèi)核也會(huì)繼續(xù)通知,直至設(shè)備數(shù)據(jù)為空為止!

1.我們已經(jīng)把一個(gè)用來從管道中讀取數(shù)據(jù)的文件句柄(RFD)添加到epoll描述符

\2. 這個(gè)時(shí)候從管道的另一端被寫入了2KB的數(shù)據(jù)

\3. 調(diào)用epoll_wait(2),并且它會(huì)返回RFD,說明它已經(jīng)準(zhǔn)備好讀取操作

\4. 然后我們讀取了1KB的數(shù)據(jù)

\5. 調(diào)用epoll_wait(2)……

ET工作模式:

如果我們?cè)诘?步將RFD添加到epoll描述符的時(shí)候使用了EPOLLET標(biāo)志,在第2步執(zhí)行了一個(gè)寫操作,第三步epoll_wait會(huì)返回同時(shí)通知的事件會(huì)銷毀。因?yàn)榈?步的讀取操作沒有讀空文件輸入緩沖區(qū)內(nèi)的數(shù)據(jù),因此我們?cè)诘?步調(diào)用epoll_wait(2)完成后,是否掛起是不確定的。epoll工作在ET模式的時(shí)候,必須使用非阻塞套接口,以避免由于一個(gè)文件句柄的阻塞讀/阻塞寫操作把處理多個(gè)文件描述符的任務(wù)餓死。

只有當(dāng)read(2)或者write(2)返回EAGAIN時(shí)(認(rèn)為讀完)才需要掛起,等待。但這并不是說每次read()時(shí)都需要循環(huán)讀,直到讀到產(chǎn)生一個(gè)EAGAIN才認(rèn)為此次事件處理完成,當(dāng)read()返回的讀到的數(shù)據(jù)長(zhǎng)度小于請(qǐng)求的數(shù)據(jù)長(zhǎng)度時(shí)(即小于sizeof(buf)),就可以確定此時(shí)緩沖中已沒有數(shù)據(jù)了,也就可以認(rèn)為此事讀事件已處理完成。

LT工作模式:

LT方式調(diào)用epoll接口的時(shí)候,它就相當(dāng)于一個(gè)速度比較快的poll(2),并且無論后面的數(shù)據(jù)是否被使用,因此他們具有同樣的職能。

當(dāng)調(diào)用 epoll_wait檢查是否有發(fā)生事件的連接時(shí),只是檢查 eventpoll對(duì)象中的 rdllist雙向鏈表是否有 epitem元素而已,如果 rdllist鏈表不為空,則把這里的事件復(fù)制到用戶態(tài)內(nèi)存中,同時(shí)將事件數(shù)量返回給用戶。因此,epoll_wait的效率非常高。epoll_ctl在向 epoll對(duì)象中添加、修改、刪除事件時(shí),從 rbr紅黑樹中查找事件也非常快,也就是說,epoll是非常高效的,它可以輕易地處理百萬級(jí)別的并發(fā)連接。

1.減少用戶態(tài)和內(nèi)核態(tài)之間的文件句柄拷貝;

2.減少對(duì)可讀可寫文件句柄的遍歷。

linux從管道中讀取數(shù)據(jù)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux從管道中讀取數(shù)據(jù),利用管道在Linux中讀取數(shù)據(jù),高效簡(jiǎn)便的方法,linux環(huán)境下,c語言怎么讀取WEB服務(wù)器的80端口上頁面的內(nèi)容,Handler消息機(jī)制(一):Linux的epoll機(jī)制的信息別忘了在本站進(jìn)行查找喔。

香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。


網(wǎng)頁題目:利用管道在Linux中讀取數(shù)據(jù),高效簡(jiǎn)便的方法(linux從管道中讀取數(shù)據(jù))
本文URL:http://www.dlmjj.cn/article/dphhgso.html