• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            利用匿名管道在父子進(jìn)程間傳遞數(shù)據(jù)

            利用匿名管道在父子進(jìn)程間傳遞數(shù)據(jù)

            進(jìn)程間傳遞數(shù)據(jù)有很多種方法,常用到的有命令行、共享內(nèi)存、內(nèi)存映射文件、剪貼板、windows消息、socket等。

            命令行的缺點(diǎn)是數(shù)據(jù)長(zhǎng)度限制。Windows2000只能傳遞256個(gè)字節(jié),內(nèi)存映射文件、共享內(nèi)存都需要一些進(jìn)程同步才能很好的配合讀寫數(shù)據(jù),剪貼板可能會(huì)被其他進(jìn)程擦數(shù)數(shù)據(jù)。當(dāng)多開的時(shí)候很難控制進(jìn)程間的對(duì)應(yīng)關(guān)系。

            一種解決方案是生成隨機(jī)命名的同步控制對(duì)象,然后利用命令行傳遞名字。同步控制對(duì)象可以通過唯一的名字再另一個(gè)進(jìn)程中獲取其引用。

            相對(duì)來說用同步對(duì)象會(huì)稍有些麻煩,匿名管道可以很好的解決這些問題。子進(jìn)程可以繼承父進(jìn)程中創(chuàng)建的句柄,父子進(jìn)程一一對(duì)應(yīng)的關(guān)系不會(huì)被打亂。而且使用簡(jiǎn)單,父子進(jìn)程可以雙向通信。

             

            用法:

            1.       首先創(chuàng)建兩條匿名管道,一條用于發(fā)送數(shù)據(jù)給子進(jìn)程,一條用于從子進(jìn)程接收數(shù)據(jù),安全描述符中指定可繼承性 saAttr.bInheritHandle = TRUE;

            2.       每條匿名管道包括兩個(gè)句柄,一個(gè)讀一個(gè)寫,可以理解為管道的兩端,從寫端寫出的數(shù)據(jù)可以從讀端讀取。所以父進(jìn)程需要一條管道來接收數(shù)據(jù),一條發(fā)送數(shù)據(jù)。

            3.       windowsIO操作都可以用WriteFile ReadFile來完成,默認(rèn)模式下數(shù)據(jù)發(fā)送和接收是阻塞的,管道的數(shù)據(jù)發(fā)送與接收也可以用重疊模式來進(jìn)行。

            4.       CreateProcess子進(jìn)程時(shí)參數(shù).bInheritHandle需要傳真,保證句柄的可繼承性。

            5.       利用STARTUPINFO傳遞管道端口給子進(jìn)程,父窗口發(fā)送數(shù)據(jù)的管道的讀端口,和父窗口等待接收數(shù)據(jù)的管道的寫端口,利用STDHANDLES來傳遞。

             

             STARTUPINFO  starinfo ={0};

                starinfo.cb 
            = sizeof(starinfo);       

                starinfo.hStdInput 
            = hSendReadPipe;

                starinfo.hStdOutput
            = hRecvWritePipe;

                starinfo.hStdError 
            = hRecvWritePipe;

                starinfo.dwFlags 
            |= STARTF_USESTDHANDLES;

             

             

            6.       子進(jìn)程從STDHANDLES獲得兩個(gè)句柄用來讀寫。

             

            HANDLE hRead  = GetStdHandle(STD_INPUT_HANDLE);   

            HANDLE hWrite 
            = GetStdHandle(STD_OUTPUT_HANDLE);

             

             

             

            下面是完整代碼:

             

             



            BOOL CreatePipe()

            {

                   SECURITY_ATTRIBUTES saAttr; 

                   saAttr.nLength 
            = sizeof(SECURITY_ATTRIBUTES); 

                   saAttr.bInheritHandle 
            = TRUE; 

                   saAttr.lpSecurityDescriptor 
            = NULL; 

                   
            /*'創(chuàng)建匿名管道*/

                   
            if (!CreatePipe(&hSendReadPipe,&hSendWritePipe, &saAttr, 0))

                   
            {

                          ::LogMsg(
            "CreatePipe failed!");

                          
            return FALSE;

                   }


                   
            /*'構(gòu)造寫句柄的復(fù)制體*/

                   
            if(!DuplicateHandle(GetCurrentProcess(), hSendWritePipe, 

                          GetCurrentProcess(), 
            &hSendWritePipeDup, 0,FALSE,DUPLICATE_SAME_ACCESS))

                   
            {

                          ::LogMsg(
            "DuplicateHandle Handle!");

                          
            return FALSE;

                   }


                   CloseHandle(hSendWritePipe);

             

                   
            //////////////////////////////////////////////////////////////////////////

                   
            if (!CreatePipe(&hRecvReadPipe,&hRecvWritePipe, &saAttr, 0))

                   
            {

                          ::LogMsg(
            "CreatePipe failed!");

                          
            return FALSE;

                   }


                   
            /*'構(gòu)造寫句柄的復(fù)制體*/

                   
            if(!DuplicateHandle(GetCurrentProcess(), hRecvReadPipe, 

                          GetCurrentProcess(), 
            &hRecvReadPipeDup, 0,FALSE,DUPLICATE_SAME_ACCESS))

                   
            {

                          ::LogMsg(
            "DuplicateHandle Handle!");

                          
            return FALSE;

                   }


                   CloseHandle(hRecvReadPipe);

                   
            return TRUE;

            }


             

             

             

             

            BOOL ReadFromPipe()

            {

                   DWORD dwReaded 
            =0;

                   
            char szBuf[255];

                   
            return ReadFile(hRecvReadPipeDup, szBuf, sizeof(szBuf), &dwReaded, NULL);     ;

            }


             

            void WaitForReply()

            {

                   
            while ( !ReadFromPipe()){}

            }


             

            BOOL WriteToPipe()

            {

                   
            char szData[1024];

                   
            int nSize = sizeof(g_cmdData);

                   CompressData((
            char*)&g_cmdData,nSize,szData);

                   

                   
            /*'對(duì)管道進(jìn)行寫操作*/

                   DWORD dwWrited 
            =0;

                   BOOL bSuccess 
            = TRUE;

                   bSuccess 
            &= WriteFile(hSendWritePipeDup, (LPCVOID)szData, nSize, &dwWrited, NULL);

             

                   CloseHandle(hSendWritePipeDup);      

                   
            if ( !bSuccess )

                   
            {

                          ::LogMsg(
            "WriteFile failed!");                           

                          
            return FALSE;

                   }
                 

                   
            return TRUE;

            }


             

            BOOL CreateGameProcess()

            {

                   
            char strDir[MAX_PATH] ={0};

                   
            char strPath[MAX_PATH]={0};

             

                   GetCurrentDirectory(MAX_PATH,strDir);

                   strcpy(strPath,strDir);    

             

            #ifdef _DEBUG

                   const 
            char* pszFileName = "\\main_debug.exe";

            #
            else

                   const 
            char* pszFileName = "\\main.exe";

            #endif

                   strcat(strPath,pszFileName);

             

                   
            if ( !CreatePipe() )

                   
            {     

                          ::LogMsg(
            "CreatePipe failed!");

                          
            return FALSE;

                   }


             

                   STARTUPINFO  starinfo 
            ={0};

                   starinfo.cb 
            = sizeof(starinfo);       

                starinfo.hStdInput 
            = hSendReadPipe;

                   starinfo.hStdOutput
            = hRecvWritePipe;

                   starinfo.hStdError 
            = hRecvWritePipe;

                starinfo.dwFlags 
            |= STARTF_USESTDHANDLES;

             

                PROCESS_INFORMATION processinfo 
            ={0};

                   

                   BOOL bRet 
            =::CreateProcess(strPath, " fromlogin", NULL,NULL,TRUE,NULL,NULL,strDir,&starinfo,&processinfo);

                   
            if(bRet)

                   
            {

            //            WaitForInputIdle(processinfo.hProcess,INFINITE);

                          dwGameProcessID 
            = processinfo.dwProcessId;

                          CloseHandle(processinfo.hProcess);

                          CloseHandle(processinfo.hThread);

                          
            return TRUE;

                   }


                   ::LogMsg(
            "CreateProcess failed!");

             

                   

                   
            return FALSE;

            }


             

             

            子進(jìn)程中接收數(shù)據(jù):

             



                   DWORD dwReaded 
            =0;                      

                   HANDLE hRead  
            = GetStdHandle(STD_INPUT_HANDLE); 

                   HANDLE hWrite 
            = GetStdHandle(STD_OUTPUT_HANDLE);

                   

                   
            if( hRead )

                   
            {                   

                          
            /*'從管道接收數(shù)據(jù)*/

                          const 
            int  nBufSize = 2048;

                          
            char        szBuf[nBufSize];

                          
            if(ReadFile(hRead, &szBuf,nBufSize, &dwReaded, NULL))

                          
            {

            }


            }

            posted on 2007-05-11 00:24 修一居士 閱讀(7783) 評(píng)論(4)  編輯 收藏 引用

            評(píng)論

            # re: 利用匿名管道在父子進(jìn)程間傳遞數(shù)據(jù)[未登錄] 2007-05-11 11:11 夢(mèng)在天涯

            不錯(cuò),有機(jī)會(huì)也用一把
            !  回復(fù)  更多評(píng)論   

            # 很感興趣,但是有個(gè)地方?jīng)]有看懂,lz可以解釋一下么,謝謝了 2007-05-26 07:50 icewind

            很感興趣,但是有個(gè)地方?jīng)]有看懂,lz可以解釋一下么,謝謝了
            BOOL bRet =::CreateProcess(strPath, " fromlogin",
            NULL,NULL,TRUE,NULL,NULL,strDir,&starinfo,&processinfo);

            if(bRet)

            {

            // WaitForInputIdle(processinfo.hProcess,INFINITE);

            /*不明白為什么要關(guān)閉句柄
            dwGameProcessID = processinfo.dwProcessId;

            CloseHandle(processinfo.hProcess);

            CloseHandle(processinfo.hThread);
            */
            return TRUE;

            }
              回復(fù)  更多評(píng)論   

            # re: 利用匿名管道在父子進(jìn)程間傳遞數(shù)據(jù) 2007-05-31 14:04 南斗

            windows 核心編程里有詳細(xì)的解釋,你創(chuàng)建得到的進(jìn)(線)程句柄你關(guān)閉它是說你不想在使用這個(gè)句柄了,并不表示關(guān)閉就是摧毀,進(jìn)(線)程句柄自己會(huì)維持一個(gè)引用計(jì)數(shù),當(dāng)它結(jié)束的時(shí)候引用計(jì)數(shù)會(huì)減一。  回復(fù)  更多評(píng)論   

            # re: 利用匿名管道在父子進(jìn)程間傳遞數(shù)據(jù)[未登錄] 2013-09-11 14:16 riverqh

            看不懂為什么在CreatePipe之后要DuplicateHandle然后CloseHandle原來由CreatePipe創(chuàng)建的通道。  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            色偷偷久久一区二区三区| 亚洲伊人久久精品影院| 99久久er这里只有精品18| 亚洲国产精品成人久久蜜臀| 久久综合狠狠综合久久激情 | 久久国产免费观看精品3| 一本久久a久久精品vr综合| 老男人久久青草av高清| 一本久久免费视频| 国产精品久久久久久久人人看| 久久亚洲AV永久无码精品| 青青青青久久精品国产h久久精品五福影院1421 | 国产三级精品久久| 久久精品国产99久久香蕉| 久久久久久一区国产精品| 亚洲国产一成久久精品国产成人综合 | 精品午夜久久福利大片| 大伊人青草狠狠久久| 久久综合综合久久狠狠狠97色88| 国产精品久久一区二区三区| 情人伊人久久综合亚洲| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 国产精品欧美亚洲韩国日本久久| 99久久精品免费看国产免费| 久久99精品久久久久久水蜜桃| 国产女人aaa级久久久级| 亚洲性久久久影院| 中文字幕热久久久久久久| 久久国产精品99精品国产| 久久青青草原综合伊人| 久久噜噜久久久精品66| 久久国产色av免费看| 精品久久久久久无码专区| 99久久精品费精品国产| 久久久午夜精品| 久久久久久国产精品免费无码| 超级碰久久免费公开视频| 久久天天婷婷五月俺也去| 国产精品一区二区久久| 午夜福利91久久福利| 国产精品美女久久久久久2018|