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

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            Windows 下的進(jìn)程間通訊及數(shù)據(jù)共享

            Windows 下的進(jìn)程間通訊及數(shù)據(jù)共享

            Windows 下有很多方法實(shí)現(xiàn)進(jìn)程間通訊,比如用 socket,管道(Pipe),信箱(Mailslot),等等。但最基本最直接的還是使用內(nèi)存共享。其他方法最終還是會(huì)繞道這里。

            可想而知,如果物理內(nèi)存只有一份,讓這份內(nèi)存在不同的進(jìn)程中,映射到各自的虛擬地址空間上,每個(gè)進(jìn)程都可以讀取同一份數(shù)據(jù),是一種最高效的數(shù)據(jù)交換方法。下面我們就討論如何實(shí)現(xiàn)它。

            共享內(nèi)存在 Windows 中是用 FileMapping 實(shí)現(xiàn)的。我們可以用 CreateFileMapping 創(chuàng)建一個(gè)內(nèi)存文件映射對(duì)象, CreateFileMapping 這個(gè) API 將創(chuàng)建一個(gè)內(nèi)核對(duì)象,用于映射文件到內(nèi)存。這里,我們并不需要一個(gè)實(shí)際的文件,所以,就不需要調(diào)用 CreateFile 創(chuàng)建一個(gè)文件, hFile 這個(gè)參數(shù)可以填寫 INVALID_HANDLE_VALUE 。但是,文件長度是需要填的。Windows 支持長達(dá) 64bit 的文件,但是這里,我們的需求一定不會(huì)超過 4G , dwMaximumSizeHigh 一定是 0 ,長度填在 dwMaximumSizeLow 即可。然后調(diào)用 MapViewOfFile 映射到當(dāng)前進(jìn)程的虛擬地址上即可。一旦用完共享內(nèi)存,再調(diào)用 UnmapViewOfFile 回收內(nèi)存地址空間。

            Windows 把 CreateFileMapping 和 MapViewOfFile 兩個(gè) API 分開做是有它的道理的。這是因?yàn)樵试S映射一個(gè)超過 4G 的文件,而地址空間最大只有 4G (實(shí)際上,一般用戶的程序只能用到 2G) , MapViewOfFile 就可以指定文件的 Offset 而只映射一部分。

            在 CreateFileMapping 的最后一個(gè)參數(shù) pszName 填寫一個(gè)名字,那么別的進(jìn)程就可以用這個(gè)名字去調(diào)用 OpenFileMapping 來打開這個(gè) FileMapping 對(duì)象,在新的進(jìn)程內(nèi)作映射。 不過,通過約定字符串的方法似乎不太優(yōu)雅。

            一個(gè)優(yōu)雅的方法是,用 DuplicateHandle 在新進(jìn)程中復(fù)制一份 FileMapping 對(duì)象出來,然后想辦法把 Handle 通知新進(jìn)程,比如用消息的方式傳遞過去。

            如果需要共享內(nèi)存的兩個(gè)進(jìn)程是父子關(guān)系,那么我們可以不用消息傳遞的方式來通知 FileMapping 的 Handle 。父進(jìn)程可以用繼承 Handle 的方式直接把 FileMapping 的 Handle 傳遞到子進(jìn)程中。當(dāng)然,在 CreateFileMapping 時(shí)就應(yīng)該設(shè)置可以被繼承的屬性。

            大約是這樣:

            SECURITY_ATTRIBUTES sa;
            sa.nLength=sizeof(sa);
            sa.lpSecurityDescriptor=NULL;
            sa.bInheritHandle=TRUE;
            handle=CreateFileMapping(INVALID_HANDLE_VALUE,&sa,PAGE_READWRITE,0,size,NULL);

            這樣,在 CreateProcess 的時(shí)候,如果 bInheritHandles 參數(shù)為 TRUE ,所有有可被繼承屬性的內(nèi)核對(duì)象都會(huì)被復(fù)制到子進(jìn)程中。

            注:內(nèi)核對(duì)象的繼承就是在 CreateProcess 創(chuàng)建子進(jìn)程,但是子進(jìn)程的主線程尚未活動(dòng)之前,內(nèi)核掃描當(dāng)前進(jìn)程中所有內(nèi)核對(duì)象,檢查出有可繼承屬性的那些,再用 DuplicateHandle 復(fù)制一份到子進(jìn)程。由于是內(nèi)核對(duì)象,在內(nèi)核中實(shí)質(zhì)只有一份,所有只是引用記數(shù)加一,父進(jìn)程和子進(jìn)程對(duì)同一內(nèi)核對(duì)象的 Handle 一定是相同的。

            復(fù)制內(nèi)核對(duì)象的過程是由 CreateProcess 內(nèi)部完成的,我們可以放心的把對(duì)象 Handle (和子進(jìn)程相同) 通過命令行傳遞給子進(jìn)程。或者,用環(huán)境變量傳遞也可以。

            值得注意的是,子進(jìn)程用完了這個(gè) FileMapping 對(duì)象后一樣需要 CloseHandle 減去引用計(jì)數(shù)。

            備注:
            CreateProcess 調(diào)用時(shí),pszCommandLine 不能直接填上一個(gè)不可修改的字符串。例如:

            CreateProcess("test.exe","test argument",...);

            這樣就是錯(cuò)誤的,因?yàn)?"test argument" 會(huì)被編譯器編譯放到不可修改的數(shù)據(jù)段中。正確的方法是:

            char cmdline[]="test argument";
            CreateProcess("test.exe",cmdline,...);

            這樣,命令行的字符串就被放在堆棧上,是可以被讀寫的。

            CreateProcess 的倒數(shù)第二個(gè)參數(shù)需要填寫一個(gè) STARTUPINFOW 結(jié)構(gòu),這個(gè)結(jié)構(gòu)很復(fù)雜,通常填起來很麻煩。我們可以復(fù)制一份父進(jìn)程的結(jié)構(gòu),再酌情修改。方法是:

            STARTUPINFO si={sizeof(si)};
            PROCESS_INFORMATION pi;
            GetStartupInfo(&si);
            CreateProcess(...,&si,& pi);

            這里, STARTUPINFO 結(jié)構(gòu)的第一個(gè)長度信息通常應(yīng)該填上,保證 GetStartupInfo(&si); 的正確執(zhí)行。

            posted on 2007-06-12 15:48 大龍 閱讀(1005) 評(píng)論(0)  編輯 收藏 引用


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


            99久久人妻无码精品系列| 99久久精品国产一区二区 | 久久婷婷综合中文字幕| 久久综合国产乱子伦精品免费| 亚洲AV日韩精品久久久久久| 国产精品久久久久久影院| 精品乱码久久久久久夜夜嗨| 伊人久久大香线蕉无码麻豆| 久久香综合精品久久伊人| 99久久精品国内| 国产香蕉久久精品综合网| 91视频国产91久久久| 波多野结衣久久| 国产精品亚洲美女久久久| 精品人妻伦九区久久AAA片69 | 久久久久无码中| 亚洲日本va中文字幕久久| 伊人久久精品线影院| 日产精品久久久一区二区| 久久久久99精品成人片三人毛片| 久久久国产亚洲精品| 久久99精品久久久久久9蜜桃| 精品久久久久久国产潘金莲| 久久成人小视频| 久久综合伊人77777麻豆| 精品国产福利久久久| 人妻无码αv中文字幕久久| 亚洲欧洲精品成人久久曰影片| 91精品婷婷国产综合久久| 久久精品无码午夜福利理论片| 久久久久亚洲AV无码专区首JN | 99久久免费国产精品| 97久久久精品综合88久久| 久久亚洲私人国产精品vA| 久久精品一区二区三区AV| 亚洲国产视频久久| 久久久久亚洲AV无码观看 | 国产V亚洲V天堂无码久久久| 亚洲国产欧洲综合997久久| 综合久久一区二区三区| 久久精品国产精品亚洲精品|