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

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

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

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

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

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

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

             

            用法:

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

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

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

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

            5.       利用STARTUPINFO傳遞管道端口給子進程,父窗口發(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.       子進程從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; 

                   
            /*'創(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);

                   

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

                   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;

            }


             

             

            子進程中接收數(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 修一居士 閱讀(7793) 評論(4)  編輯 收藏 引用

            評論

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

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

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

            很感興趣,但是有個地方?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ù)  更多評論   

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

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

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

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

            導(dǎo)航

            <2012年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            統(tǒng)計

            常用鏈接

            留言簿(3)

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久成人精品| 99久久99久久精品国产| 久久精品国产亚洲av麻豆图片| 日韩欧美亚洲综合久久| 久久亚洲日韩精品一区二区三区| 久久er99热精品一区二区| 狠狠色综合久久久久尤物| 亚洲精品无码久久久久久| 大伊人青草狠狠久久| 色婷婷噜噜久久国产精品12p| 久久精品中文无码资源站| 久久久久亚洲AV成人网| 久久丫精品国产亚洲av不卡| 精品无码久久久久久国产| 久久久久无码精品国产| 亚洲精品国产第一综合99久久| 久久国产精品成人影院| 久久亚洲精品国产亚洲老地址| 天天久久狠狠色综合| 韩国免费A级毛片久久| 久久精品桃花综合| 久久久久99精品成人片| 亚洲国产精品久久久久| 久久国产亚洲高清观看| 97久久国产综合精品女不卡| 免费一级做a爰片久久毛片潮| 国产精品久久网| av无码久久久久不卡免费网站 | 久久免费视频一区| 狠狠色噜噜狠狠狠狠狠色综合久久 | 久久亚洲中文字幕精品一区四 | av国内精品久久久久影院| 久久久www免费人成精品| 一本一本久久a久久精品综合麻豆| 久久综合九色综合97_久久久| .精品久久久麻豆国产精品| 久久久久久亚洲精品成人| 久久久久亚洲AV无码永不| 亚洲AV无码久久精品色欲| 无码伊人66久久大杳蕉网站谷歌| 狠狠色丁香久久婷婷综合_中|