• <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創建的通道。  回復  更多評論   

            導航

            <2007年5月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統計

            常用鏈接

            留言簿(3)

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久国产劲爆AV内射—百度| 亚洲人成伊人成综合网久久久 | 国产成人99久久亚洲综合精品| 久久国产精品一国产精品金尊| 亚洲va久久久噜噜噜久久天堂| 久久国产精品久久国产精品| 久久国产成人亚洲精品影院| 伊人久久大香线蕉综合网站| 日韩精品久久久久久免费| 亚洲乱亚洲乱淫久久| 亚洲欧美精品一区久久中文字幕 | 久久久久久综合一区中文字幕| 精品久久久久中文字幕一区| 久久99精品国产麻豆宅宅| 久久电影网2021| 人妻少妇久久中文字幕一区二区 | 亚洲中文久久精品无码ww16| 久久免费国产精品一区二区| 久久久久亚洲精品日久生情| 久久精品九九亚洲精品天堂 | 久久久久无码精品| 久久大香香蕉国产| 久久精品中文字幕一区| 国产综合免费精品久久久| 久久人人爽人人爽人人片av高请| 久久精品国产精品亚洲人人 | 久久人人超碰精品CAOPOREN| 久久大香香蕉国产| 久久天天躁狠狠躁夜夜96流白浆| 欧美亚洲国产精品久久久久| 欧美777精品久久久久网| 亚洲AV无一区二区三区久久| 亚洲国产成人久久综合区| 久久久艹| 午夜精品久久久久久| 国产精品欧美久久久久无广告 | 久久久久人妻一区精品 | 久久精品国产亚洲AV忘忧草18| 欧美一级久久久久久久大| 久久激情亚洲精品无码?V| 国产农村妇女毛片精品久久 |