• <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>

            利用匿名管道在父子進程間傳遞數據

            利用匿名管道在父子進程間傳遞數據

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

            命令行的缺點是數據長度限制。Windows2000只能傳遞256個字節,內存映射文件、共享內存都需要一些進程同步才能很好的配合讀寫數據,剪貼板可能會被其他進程擦數數據。當多開的時候很難控制進程間的對應關系。

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

            相對來說用同步對象會稍有些麻煩,匿名管道可以很好的解決這些問題。子進程可以繼承父進程中創建的句柄,父子進程一一對應的關系不會被打亂。而且使用簡單,父子進程可以雙向通信。

             

            用法:

            1.       首先創建兩條匿名管道,一條用于發送數據給子進程,一條用于從子進程接收數據,安全描述符中指定可繼承性 saAttr.bInheritHandle = TRUE;

            2.       每條匿名管道包括兩個句柄,一個讀一個寫,可以理解為管道的兩端,從寫端寫出的數據可以從讀端讀取。所以父進程需要一條管道來接收數據,一條發送數據。

            3.       windowsIO操作都可以用WriteFile ReadFile來完成,默認模式下數據發送和接收是阻塞的,管道的數據發送與接收也可以用重疊模式來進行。

            4.       CreateProcess子進程時參數.bInheritHandle需要傳真,保證句柄的可繼承性。

            5.       利用STARTUPINFO傳遞管道端口給子進程,父窗口發送數據的管道的讀端口,和父窗口等待接收數據的管道的寫端口,利用STDHANDLES來傳遞。

             

             STARTUPINFO  starinfo ={0};

                starinfo.cb 
            = sizeof(starinfo);       

                starinfo.hStdInput 
            = hSendReadPipe;

                starinfo.hStdOutput
            = hRecvWritePipe;

                starinfo.hStdError 
            = hRecvWritePipe;

                starinfo.dwFlags 
            |= STARTF_USESTDHANDLES;

             

             

            6.       子進程從STDHANDLES獲得兩個句柄用來讀寫。

             

            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; 

                   
            /*'創建匿名管道*/

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

                   
            {

                          ::LogMsg(
            "CreatePipe failed!");

                          
            return FALSE;

                   }


                   
            /*'構造寫句柄的復制體*/

                   
            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;

                   }


                   
            /*'構造寫句柄的復制體*/

                   
            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);

                   

                   
            /*'對管道進行寫操作*/

                   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;

            }


             

             

            子進程中接收數據:

             



                   DWORD dwReaded 
            =0;                      

                   HANDLE hRead  
            = GetStdHandle(STD_INPUT_HANDLE); 

                   HANDLE hWrite 
            = GetStdHandle(STD_OUTPUT_HANDLE);

                   

                   
            if( hRead )

                   
            {                   

                          
            /*'從管道接收數據*/

                          const 
            int  nBufSize = 2048;

                          
            char        szBuf[nBufSize];

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

                          
            {

            }


            }

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

            評論

            # re: 利用匿名管道在父子進程間傳遞數據[未登錄] 2007-05-11 11:11 夢在天涯

            不錯,有機會也用一把
            !  回復  更多評論   

            # 很感興趣,但是有個地方沒有看懂,lz可以解釋一下么,謝謝了 2007-05-26 07:50 icewind

            很感興趣,但是有個地方沒有看懂,lz可以解釋一下么,謝謝了
            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;

            }
              回復  更多評論   

            # re: 利用匿名管道在父子進程間傳遞數據 2007-05-31 14:04 南斗

            windows 核心編程里有詳細的解釋,你創建得到的進(線)程句柄你關閉它是說你不想在使用這個句柄了,并不表示關閉就是摧毀,進(線)程句柄自己會維持一個引用計數,當它結束的時候引用計數會減一。  回復  更多評論   

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

            看不懂為什么在CreatePipe之后要DuplicateHandle然后CloseHandle原來由CreatePipe創建的通道。  回復  更多評論   

            導航

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

            統計

            常用鏈接

            留言簿(3)

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            香港aa三级久久三级| 久久精品国产久精国产思思| 精品无码久久久久国产| 亚洲精品tv久久久久| 久久精品国产清自在天天线| 国产亚洲精久久久久久无码AV| 国产精品久久久久影院色 | 久久久噜噜噜www成人网| 亚洲精品国精品久久99热一| 亚洲精品无码久久久久| 久久久国产精品亚洲一区| 久久精品国产清高在天天线| 99久久婷婷免费国产综合精品| 国产精品一区二区久久不卡| 久久99精品久久久久久hb无码| 精品久久一区二区三区| 7国产欧美日韩综合天堂中文久久久久 | 久久亚洲精品无码AV红樱桃| 日韩精品久久无码人妻中文字幕| 亚洲国产精品无码久久98| 国产成人久久精品激情| 国产成人精品久久亚洲| 一97日本道伊人久久综合影院| 久久精品免费一区二区| 国内精品人妻无码久久久影院 | 久久精品无码一区二区三区免费| 久久99精品国产麻豆不卡| 久久久亚洲AV波多野结衣| 99久久超碰中文字幕伊人| 久久久精品波多野结衣| 精品熟女少妇AV免费久久| 久久精品国产亚洲一区二区| 日本亚洲色大成网站WWW久久| 亚洲狠狠婷婷综合久久蜜芽| 狠狠久久综合| 久久久久AV综合网成人| 久久综合一区二区无码| 久久精品国产精品青草| 2021国产精品久久精品| 久久精品成人影院| a高清免费毛片久久|