第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

對(duì)輪詢流使用輪詢功能

對(duì)輪詢流使用輪詢功能

C
慕萊塢森 2019-09-26 15:24:54
對(duì)輪詢流使用輪詢功能我正在嘗試使用C中的poll函數(shù)來(lái)實(shí)現(xiàn)通信系統(tǒng)的客戶端-服務(wù)器類型。流程如下:主程序派生一個(gè)子進(jìn)程子進(jìn)程調(diào)用exec函數(shù)執(zhí)行some_binary父級(jí)和子級(jí)交替發(fā)送消息,發(fā)送的每個(gè)消息都取決于收到的最后一條消息。我嘗試使用來(lái)實(shí)現(xiàn)此功能poll,但由于子進(jìn)程緩沖其輸出,導(dǎo)致我的poll超時(shí)調(diào)用而遇到問(wèn)題。這是我的代碼:int main() {char *buffer = (char *) malloc(1000);int n;pid_t pid; /* pid of child process */int rpipe[2]; /* pipe used to read from child process */int wpipe[2]; /* pipe used to write to child process */pipe(rpipe);pipe(wpipe);pid = fork();if (pid == (pid_t) 0){     /* child */     dup2(wpipe[0], STDIN_FILENO);     dup2(rpipe[1], STDOUT_FILENO);     close(wpipe[0]); close(rpipe[0]);     close(wpipe[1]); close(rpipe[1]);     if (execl("./server", "./server", (char *) NULL) == -1)     {         fprintf(stderr, "exec failed\n");         return EXIT_FAILURE;     }            return EXIT_SUCCESS;}else{     /* parent */     /* close the other ends */     close(wpipe[0]);     close(rpipe[1]);     /*        poll to check if write is good to go                  This poll succeeds, write goes through         */     struct pollfd pfds[1];     pfds[0].fd = wpipe[1];     pfds[0].events = POLLIN | POLLOUT;     int pres = poll(pfds, (nfds_t) 1, 1000);     if (pres > 0)     {         if (pfds[0].revents & POLLOUT)         {             printf("Writing data...\n");             write(wpipe[1], "hello\n", 6);         }     }     /*          poll to check if there's something to read.         This poll times out because the child buffers its stdout stream.     */     pfds[0].fd = rpipe[0];     pfds[0].events = POLLIN | POLLOUT;     pres = poll(pfds, (nfds_t) 1, 1000);     if (pres > 0)     {         if (pfds[0].revents & POLLIN)         {             printf("Reading data...\n");             int n = read(rpipe[0], buffer, 1000);             buffer[n] = '\0';             printf("child says:\n%s\n", buffer);         }     }     kill(pid, SIGTERM);     return EXIT_SUCCESS;}}如何防止poll由于緩沖而導(dǎo)致呼叫超時(shí)?編輯:我希望程序即使在execed二進(jìn)制文件位于外部時(shí)也能運(yùn)行,即我無(wú)法控制代碼-像unix命令,例如cator ls。
查看完整描述

3 回答

?
幕布斯6054654

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個(gè)贊

正如我在對(duì)上一個(gè)問(wèn)題的相關(guān)回答中所回答的那樣,您需要實(shí)現(xiàn)一個(gè)事件循環(huán);顧名思義,它是循環(huán)的,因此您應(yīng)該在父進(jìn)程中進(jìn)行編碼:

while (1) { // simplistic event loop!
   int status=0;
   if (waitpid(pid, &status, WNOHANG) == pid)
      { // clean up, child process has ended
        handle_process_end(status);
        break;
      };
   struct pollpfd pfd[2];
   memset (&pfd, 0, sizeof(pfd)); // probably useless but dont harm
   pfd[0].fd = rpipe[0];
   pfd[0].events = POLL_IN;
   pfd[1].fd = wpipe[1];
   pfd[0].event = POLL_OUT;
   #define DELAY 5000 /* 5 seconds */
   if (poll(pfd, 2, DELAY)>0) {
      if (pfd[0].revents & POLL_IN) {
         /* read something from rpipe[0]; detect end of file; 
            you probably need to do some buffering, because you may 
            e.g. read some partial line chunk written by the child, and 
            you could only handle full lines. */
      };
      if (pfd[1].revents & POLL_OUT) {
         /* write something on wpipe[1] */
      };
   }
   fflush(NULL);} /* end while(1) */

您無(wú)法預(yù)測(cè)管道的可讀或可寫(xiě)順序,并且這種情況可能會(huì)發(fā)生很多次。當(dāng)然,涉及很多緩沖(在父進(jìn)程中),我將詳細(xì)信息留給您。...您對(duì)子進(jìn)程中的緩沖沒(méi)有影響(某些程序檢測(cè)到它們的輸出是否為isatty)。

上面類似的事件輪詢循環(huán)為您避免死鎖情況,因?yàn)樽舆M(jìn)程的stdout管道已滿,子進(jìn)程被阻塞,而父進(jìn)程由于管道已滿而被阻止寫(xiě)入(寫(xiě)入子stdin管道)父進(jìn)程:循環(huán)時(shí),只要輪詢某些數(shù)據(jù)在輸入管道上即可讀?。醋舆M(jìn)程的stdout),便會(huì)讀取數(shù)據(jù),并且一旦輪詢輸出管道可寫(xiě)(即未滿)就可以寫(xiě)入一些數(shù)據(jù)。您無(wú)法預(yù)先預(yù)測(cè)這些事件“孩子的輸出可被父母讀取”和“孩子的輸入可被父母寫(xiě)入”的順序。

我建議閱讀高級(jí)Linux編程,其中有幾章解釋了這些問(wèn)題!

順便說(shuō)一句,我的簡(jiǎn)單事件循環(huán)有點(diǎn)不對(duì):如果子進(jìn)程終止并且某些數(shù)據(jù)保留在其stdout管道中,則不會(huì)完成其讀取。您可以waitpidpoll

另外,不要期望單個(gè)write(來(lái)自子進(jìn)程)進(jìn)入管道會(huì)觸發(fā)read父進(jìn)程中的一個(gè)。換句話說(shuō),沒(méi)有消息長(zhǎng)度的概念。但是,POSIX知道PIPE_MAX...。請(qǐng)參閱其編寫(xiě)文檔。也許您的緩沖區(qū)傳遞到readwrite應(yīng)該的PIPE_MAX大小。

我重復(fù)一遍:您需要在事件循環(huán)內(nèi)調(diào)用,poll并且很有可能poll會(huì)被調(diào)用多次(因?yàn)檠h(huán)將重復(fù)多次!),并且將以不可預(yù)測(cè)(且不可重現(xiàn))的順序報(bào)告可讀或可寫(xiě)的管道末端!程序的第一次運(yùn)行可能報(bào)告“ rpipe[0]可讀”,read從中可以得到324個(gè)字節(jié),重復(fù)事件循環(huán),poll說(shuō)“ wpipe[1]可寫(xiě)”,可以write向其重復(fù)10個(gè)字節(jié),然后重復(fù)事件循環(huán),poll則表明“ rpipe[0]可讀”,您read從中讀取110個(gè)字節(jié),重復(fù)事件循環(huán),poll再次告訴“ rpipe[0]可讀”,您read4096個(gè)字節(jié),等等,等等...在相同環(huán)境中第二次運(yùn)行同一程序?qū)a(chǎn)生不同的事件,例如:poll說(shuō)“ wpipe[1]可寫(xiě)”,您write對(duì)它寫(xiě)了1000個(gè)字節(jié),重復(fù)循環(huán),poll說(shuō)“ rpipe[0]可讀”等...

注意:您的問(wèn)題不是子程序(“客戶端”)中的緩沖,我們認(rèn)為您無(wú)法更改。因此,重要的不是其中的緩沖數(shù)據(jù),而是真正的輸入和輸出(這是父進(jìn)程唯一可以觀察到的內(nèi)容;內(nèi)部子緩沖區(qū)與父進(jìn)程無(wú)關(guān)),即子程序能夠執(zhí)行的數(shù)據(jù)真正 讀?。?)寫(xiě)入(2)。并且如果通過(guò)pipe(7),則此類數(shù)據(jù)將在父進(jìn)程中變?yōu)?a >poll(2)-(并且您的父進(jìn)程可以在或之后的更新字段中readwrite其中的一部分)。順便說(shuō)一句,如果您確實(shí)編碼了孩子,別忘了打電話給POLL_INPOLL_OUTreventspollfflush 在里面合適的地方。


查看完整回答
反對(duì) 回復(fù) 2019-09-26
?
紫衣仙女

TA貢獻(xiàn)1839條經(jīng)驗(yàn) 獲得超15個(gè)贊

您的代碼中似乎有兩個(gè)問(wèn)題。默認(rèn)情況下,“ stdout”是緩沖的,因此服務(wù)器應(yīng)顯式刷新它:

printf("I received %s\n", buffer);fflush(stdout);

并且POLLOUT在嘗試讀取時(shí)主程序不應(yīng)注冊(cè)(但您可能想要注冊(cè)POLLERR):

pfds[0].fd = rpipe[0];pfds[0].events = POLLIN | POLLERR;

通過(guò)這些修改,您可以獲得預(yù)期的輸出:

$ ./main寫(xiě)入數(shù)據(jù)...讀取數(shù)據(jù)...孩子說(shuō):我打招呼了

通常,您還應(yīng)該檢查的返回值poll(),并在必要時(shí)重復(fù)調(diào)用(例如,在系統(tǒng)調(diào)用中斷或超時(shí)的情況下)。


查看完整回答
反對(duì) 回復(fù) 2019-09-26
?
SMILET

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊

從您的問(wèn)題中我感覺(jué)到您擁有服務(wù)器代碼,因此可以對(duì)其進(jìn)行修改。即使使用“ cat”,如果您按照pfds[0].events = POLLIN | POLLERR我的建議進(jìn)行設(shè)置,它似乎也可以工作。但是,如果外部程序?qū)ζ漭敵鲞M(jìn)行緩沖(因此不會(huì)寫(xiě)入stdout),那么我認(rèn)為您無(wú)法做任何事情。

查看完整回答
反對(duì) 回復(fù) 2019-09-26
  • 3 回答
  • 0 關(guān)注
  • 608 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)