亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 漫談兼容內核之十六:windows的進程間通信.txt

?? 漫談系統內核內幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 5 頁
字號:
漫談兼容內核之十六:Windows的進程間通信

[i]毛德操[/i]

    對于任何一個現代的操作系統,進程間通信都是其系統結構的一個重要組成部分。而說到Windows的進程(線程)間通信,那就要看是在什么意義上說了。因為正如“Windows的跨進程操作”那篇漫談中所述,在Windows上一個進程甚至可以“打開”另一個進程,并在對方的用戶空間分配內存、再把程序或數據拷貝過去,最后還可以在目標進程中創建一個線程、讓它為所欲為。顯然,這已經不只是進程間的“通信”,而是進程間“操縱”了。但是這畢竟屬于另類,我們在這里要談論的是“正規”的進程間通信。
    不管是兩個甚么樣的實體,凡是要通信就得滿足一個必要條件,那就是存在雙方都可以訪問的介質。顧名思義,進程間通信就是在不同進程之間傳播或交換信息,那么不同進程之間存在著什么雙方都可以訪問的介質呢?進程的用戶空間是互相獨立的,一般而言是不能互相訪問的,唯一的例外是共享內存區。但是,系統空間卻是“公共場所”,所以內核顯然可以提供這樣的條件。除此以外,那就是雙方都可以訪問的外設了。在這個意義上,兩個進程當然也可以通過磁盤上的普通文件交換信息,或者通過“注冊表”或其它數據庫中的某些表項和記錄交換信息。廣義上這也是進程間通信的手段,但是一般都不把這算作“進程間通信”。因為那些通信手段的效率太低了,而人們對進程間通信的要求是要有一定的實時性。
    但是,對于實際的應用而言,光有信息傳播的實時性往往還不夠。不妨以共享內存區(Section)為例來說明這個問題。共享內存區顯然可以用作進程間通信的手段,兩個進程把同一組物理內存頁面分別映射到自己的用戶空間,然后一個進程往里面寫,另一個進程就可以讀到所寫入的內容。從信息傳播的角度看,這個過程是“即時”的,有著很高的實時性,但是讀取者怎么知道寫入者已經寫入了一些數據呢?要是共享內存區的物理頁面能產生中斷請求就好了,可是它不能。讓讀取者輪詢、或者定時輪詢、那當然也可以,但是效率就降下來了。所以,這里還需要有通信雙方行為上的協調、或稱進程間的“同步”。注意所謂“同步”并不是說雙方應該同時讀或同時寫,而是讓雙方的行為得以有序、緊湊地進行。
    綜上所述,一般所說的“進程間通信”其實是狹義的、帶限制條件的。總的來說,對于進程間通信有三方面的要求:
  l 具有不同進程之間傳播或交換信息的手段
  l 進程間傳播或交換信息的手段應具有一定程度的實時性
  l 具有進程間的協調(同步)機制。
    此外,“進程間通信”一般是指同一臺機器上的進程間通信。通過網絡或通信鏈路進行的跨主機的通信一般不歸入進程間通信的范疇,雖然這種通信通常也確實是發生于進程之間。不過網絡通信往往也可以作用于本機的不同進程之間,這里并沒有明確的界線。這樣一來范圍就廣了,所以本文在介紹Windows的進程間通信時以其內核是否專門為具體的機制提供了系統調用為準。這樣,例如用于網絡通信的Winsock機制是作為設備驅動實現的,內核并沒有為此提供專門的系統調用,所以本文就不把它算作進程間通信。
    先看上面三方面要求的第一項,即同一機器上的不同進程之間傳播或交換信息的手段,這無非就是幾種可能:
    l 通過用戶空間的共享內存區。
    l 通過內核中的變量、數據結構、或緩沖區。
    l 通過外設的存儲效應。但是一般所講操作系統內核的“進程間通信”機制都把這排除在外。
    由于通過外設進行的進程間通信一般而言實時性不是很好,所以考慮到上述第二方面的要求就把它給排除掉了。
    再看進程間的同步機制。如前所述,進程間同步的目的是要讓通信的雙方(或多方) 行為得以有序、緊湊地進行。所以本質上就是雙方(或多方)之間的等待(睡眠)/喚醒機制,這就是為什么要在上一篇漫談中先介紹等待/喚醒機制的原因。注意這里的“等待”意味著主動進入睡眠,一般而言,所謂“進程間同步”就是建立在(主動)睡眠/喚醒機制基礎上的同步。不主動進入睡眠的同步也是有的,例如“空轉鎖(Spinlock)”就是,但是那樣太浪費CPU資源了。再說,在單CPU的系統中,如果是在調度禁區中使用Spinlock,還會引起死鎖。所以,一般不把Spinlock算作進程間同步手段。在操作系統理論中,“信號量(Semaphore)”是基本的進程間同步機制,別的大都是在此基礎上派生出來的。
    另一方面,進程間同步的實現本身就需要有進程間的信息傳遞作為基礎,例如“喚醒”這個動作就蘊含著信息的傳遞。所以,進程間同步其實也是進程間通信,只不過是信息量比較小、或者很小的進程間通信。換言之,帶有進程間同步的進程間通信,實際上就是先以少量信息的傳遞使雙方的行為得到協調,再在此基礎上交換比較大量的信息。如果需要傳遞的信息量本來就很小,那么這里的第二步也就不需要了。所以,進程間同步就是(特殊的)進程間通信。
    注意這里所說的進程間通信實際上是線程間通信,特別是分屬于不同進程的線程之間的通信。因為在Windows中線程才是運行的實體,而進程不是。但是上述的原理同樣適用于同一進程內部的線程間通信。屬于同一進程的線程共享同一個用戶空間,所以整個用戶空間都成了共享內存區。如果兩個線程都訪問同一個變量或數據結構,那么實際上就構成了線程間通信(或許是在不知不覺間)。這里仍有雙方如何同步的問題,但是既然是共享用戶空間,就有可能在用戶空間構筑這樣的同步機制。所以,一般而言,進程間通信需要內核的支持,而同一進程中的線程間通信則也可以在用戶空間(例如在DLL中)實現。在下面的敘述中,“進程間通信”和“線程間通信”這兩個詞常常是混用的,讀者應注意領會。

    Windows內核所支持的進程間通信手段有:
    l 共享內存區(Section)。
    l 信號量(Semaphore)。
    l 互斥門(Mutant)。
    l 事件(Event)。
    l 特殊文件“命名管道(Named Pipe)”和“信箱(Mail Slot)”。
    此外,本地過程調用、即LPC,雖然并非以進程間通信機制的面貌出現,實際上卻是建立在進程間通信的基礎上,并且本身就是一種獨特的進程間通信機制。還有,Windows的Win32K模塊提供了一種線程之間的報文傳遞機制,一般用作“窗口”之間的通信手段,顯然也應算作進程間通信,只不過這是由Win32K的“擴充系統調用”支持的,而并非由基本的系統調用所支持。所以,還應增加以下兩項。
    l 端口(Port)和本地過程調用(LPC)。
    l 報文(Message)。
    注:“Undocumented Windows 2000 Secrets”書中還列出了另一組用于“通道(Channel)”的系統調用,例如NtOpenChannel()、NtListenChannel()、NtSendWaitReplyChannel()等等,從這些系統調用函數名看來,這應該也是一種進程間通信機制,但是“Windows NT/2000 Native API Reference”書中說這些函數均未實現,調用后只是返回出錯代碼“STATUS_NOT_IMPLEMENTED”,“Microsoft Windows Internals”書中則并未提及。在ReactOS的代碼中也未見實現。
    下面逐一作些介紹。

1. 共享內存區(Section)
    如前所述,共享內存區是可以用于進程間通信的。但是,離開進程間同步機制,它的效率就不會高,所以共享內存區單獨使用并不是一種有效的進程間通信機制。
    使用的方法是:先以雙方約定的名字創建一個Section對象,各自加以打開,再各自將其映射到自己的用戶空間,然后就可以通過常規的內存讀寫(例如通過指針)進行通信了。
    要通過共享內存區進行通信時,首先要通過NtCreateSection()創建一個共享內存區對象。從程序的結構看,幾乎所有對象的創建、即所有形似NtCreateXYZ()的函數的代碼都是基本相同的,所以下面列出NtCreateSection()的代碼,以后對類似的代碼就不再列出了。

[code]NTSTATUS STDCALL
NtCreateSection (OUT PHANDLE SectionHandle,
                 IN ACCESS_MASK DesiredAccess,
                 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                 IN PLARGE_INTEGER MaximumSize OPTIONAL,
                 IN ULONG SectionPageProtection OPTIONAL,
                 IN ULONG AllocationAttributes,
                 IN HANDLE FileHandle OPTIONAL)
{
   . . . . . .
   PreviousMode = ExGetPreviousMode();
  
   if(MaximumSize != NULL && PreviousMode != KernelMode)
   {
     _SEH_TRY
     {
       ProbeForRead(MaximumSize,
                    sizeof(LARGE_INTEGER),
                    sizeof(ULONG));
       /* make a copy on the stack */
       SafeMaximumSize = *MaximumSize;
       MaximumSize = &SafeMaximumSize;
     }
     _SEH_HANDLE
     {
       Status = _SEH_GetExceptionCode();
     }
     _SEH_END;
    
     if(!NT_SUCCESS(Status))
     {
       return Status;
     }
   }
  
   /*
    * Check the protection
    */
   if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) !=
         SectionPageProtection)
   {
      return(STATUS_INVALID_PAGE_PROTECTION);
   }

   Status = MmCreateSection(&SectionObject, DesiredAccess, ObjectAttributes,
                            MaximumSize, SectionPageProtection,
                            AllocationAttributes, FileHandle, NULL);
   if (NT_SUCCESS(Status))
   {
      Status = ObInsertObject ((PVOID)SectionObject, NULL,
                               DesiredAccess, 0, NULL, SectionHandle);
      ObDereferenceObject(SectionObject);
   }

   return Status;
}[/code]
    雖然名曰“Create”,實際上卻是“創建并打開”,參數SectionHandle就是用來返回打開后的Handle。參數DesiredAccess說明所創建的對象允許什么樣的訪問,例如讀、寫等等。ObjectAttributes則說明對象的名稱,打開以后是否允許遺傳,以及與對象保護有關的特性、例如訪問權限等等。這幾個參數對于任何對象的創建都一樣,而其余幾個參數就是專為共享內存區的特殊需要而設的了。其中MaximumSize當然是共享內存區大小的上限,而SectionPageProtection與頁面的保護有關。AllocationAttributes通過一些標志位說明共享區的性質和用途,例如可執行映像或數據文件。最后,共享緩沖區往往都是以磁盤文件作為后盾的,為此需要先創建或打開相應的文件,然后把FileHandle作為參數傳給NtCreateSection()。不過用于進程間通信的共享內存區是空白頁面,其內容并非來自某個文件,所以FileHandle為NULL。
    顯然,創建共享內存區的實質性操作是由MmCreateSection()完成的。對于其它的對象,往往也都有類似的函數。我們看一下MmCreateSection()的代碼:

[code][NtCreateSection() > MmCreateSection()]

NTSTATUS STDCALL
MmCreateSection (OUT PSECTION_OBJECT   * SectionObject,
                 IN ACCESS_MASK         DesiredAccess,
                 IN POBJECT_ATTRIBUTES  ObjectAttributes   OPTIONAL,
                 IN PLARGE_INTEGER      MaximumSize,
                 IN ULONG                 SectionPageProtection,
                 IN ULONG                 AllocationAttributes,
                 IN HANDLE               FileHandle   OPTIONAL,
                 IN PFILE_OBJECT          File   OPTIONAL)
{
   if (AllocationAttributes & SEC_IMAGE)
   {
      return(MmCreateImageSection(SectionObject, DesiredAccess, ObjectAttributes,
                                  MaximumSize, SectionPageProtection,
                                  AllocationAttributes, FileHandle));
   }

   if (FileHandle != NULL)
   {
      return(MmCreateDataFileSection(SectionObject, DesiredAccess, ObjectAttributes,
                                   MaximumSize, SectionPageProtection,
                                   AllocationAttributes, FileHandle));
   }

   return(MmCreatePageFileSection(SectionObject, DesiredAccess, ObjectAttributes,
                           MaximumSize, SectionPageProtection, AllocationAttributes));
}[/code]
    參數AllocationAttributes中的SEC_IMAGE標志位為1表示共享內存區的內容是可執行映像(因而必需符合可執行映像的頭部結構)。而FileHandle為1表示共享內存區的內容來自文件,既然不是可執行映像那就是數據文件了;否則就并非來自文件,那就是用于進程間通信的空白頁面了。最后一個參數File的用途不明,似乎并無必要。我們現在關心的是空白頁面的共享內存區,具體的對象是由MmCreatePageFileSection()創建的,我們就不往下看了。注意這里還不涉及共享內存區的地址,因為尚未映射。
    參與通信的雙方通過同一個共享內存區進行通信,所以不能各建各的共享內存區,至少有一方需要打開已經創建的共享內存區,這是通過NtOpenSection()完成的:

[code]NTSTATUS STDCALL
NtOpenSection(PHANDLE   SectionHandle,
              ACCESS_MASK  DesiredAccess,
              POBJECT_ATTRIBUTES ObjectAttributes)
{
   HANDLE hSection;
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
  
   PreviousMode = ExGetPreviousMode();
  
   if(PreviousMode != KernelMode)
   {
     _SEH_TRY. . . . . . _SEH_END;
   }
   Status = ObOpenObjectByName(ObjectAttributes, MmSectionObjectType,
                               NULL, PreviousMode, DesiredAccess,
                               NULL, &hSection);
   if(NT_SUCCESS(Status))
   {
     _SEH_TRY
     {
       *SectionHandle = hSection;
     }
     _SEH_HANDLE
     {
       Status = _SEH_GetExceptionCode();
     }
     _SEH_END;
   }

   return(Status);
}[/code]
    這里實質性的操作是ObOpenObjectByName(),讀者想必已經熟悉。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品区一区二区| 亚洲一区二区三区四区中文字幕| 99久久国产综合色|国产精品| 蜜桃在线一区二区三区| 亚洲一卡二卡三卡四卡五卡| 精品亚洲成a人| 奇米色777欧美一区二区| 天天色天天操综合| 婷婷激情综合网| 99免费精品在线观看| 91色九色蝌蚪| 欧美中文字幕亚洲一区二区va在线 | 日韩欧美一级二级三级| 日韩精品在线一区二区| 亚洲自拍偷拍网站| 成人精品一区二区三区四区 | 亚洲国产精品国自产拍av| 国产亲近乱来精品视频| 中文字幕一区在线| 一区二区欧美在线观看| 无吗不卡中文字幕| 欧美艳星brazzers| 日韩一区二区三区在线| 久久久一区二区三区| 国产精品白丝在线| 亚洲影视在线播放| 91美女片黄在线观看| 综合久久久久综合| 三级久久三级久久久| 国产精品99久久久久久久女警| 成人av在线观| 欧美一区二区三区白人| 久久久综合激的五月天| 激情成人午夜视频| 在线观看国产精品网站| 亚洲精选在线视频| 久久99国产精品麻豆| 欧美精品tushy高清| 国产精品乱子久久久久| 午夜伊人狠狠久久| 成人av在线资源网站| 国产精品视频线看| 不卡的av在线播放| 亚洲人成小说网站色在线 | 精品一区二区三区在线视频| 91精品国产综合久久香蕉的特点| 久久久三级国产网站| 国产精品亚洲专一区二区三区| 国产农村妇女毛片精品久久麻豆| 丁香婷婷综合五月| 欧美大片在线观看一区二区| 久久精品国产亚洲高清剧情介绍| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 色呦呦日韩精品| 五月婷婷久久丁香| 精品国产sm最大网站| 亚洲一区在线电影| 欧美一区二区三区在线视频| 国产在线不卡一区| 欧美一区二区三区四区五区| 国产最新精品精品你懂的| 国产日产欧产精品推荐色| 99精品视频免费在线观看| 亚洲第四色夜色| 久久青草欧美一区二区三区| 91在线视频官网| 肉丝袜脚交视频一区二区| 久久综合色婷婷| 国产一区二区在线免费观看| 成人欧美一区二区三区黑人麻豆 | 懂色av一区二区三区免费看| 亚洲最大的成人av| 精品久久国产老人久久综合| 成人伦理片在线| 视频一区视频二区中文字幕| 国产欧美日韩在线看| 欧美午夜精品理论片a级按摩| 麻豆国产精品视频| 一区二区三区欧美在线观看| 日韩三级精品电影久久久 | 亚洲福利视频一区| 91欧美一区二区| 免费成人在线观看| 椎名由奈av一区二区三区| 欧美不卡一区二区三区| 色婷婷综合久久久久中文一区二区| 蜜臀av性久久久久蜜臀aⅴ| 亚洲人成精品久久久久| 精品国产乱码久久久久久影片| 色拍拍在线精品视频8848| 国产精品一区二区无线| 日本亚洲免费观看| 精品国产91久久久久久久妲己| 91麻豆国产福利在线观看| 国产在线麻豆精品观看| 日韩精品欧美精品| 亚洲午夜免费电影| 国产精品区一区二区三区| 精品精品国产高清a毛片牛牛| 欧美喷水一区二区| 久久99精品久久只有精品| 亚洲曰韩产成在线| 亚洲少妇30p| 国产精品天干天干在观线| 欧美电影免费观看高清完整版在线 | 91麻豆国产香蕉久久精品| 国产成人av一区二区三区在线 | 在线播放欧美女士性生活| 成人毛片视频在线观看| 精彩视频一区二区| 蜜桃一区二区三区在线| 日日夜夜精品视频天天综合网| 亚洲与欧洲av电影| 亚洲一区二区黄色| 亚洲va韩国va欧美va精品| 一区二区三区在线免费观看| 亚洲欧美另类综合偷拍| 亚洲三级免费观看| 亚洲欧美日韩中文播放| 亚洲女子a中天字幕| 成人免费一区二区三区视频 | 日韩免费观看2025年上映的电影| 7777精品伊人久久久大香线蕉完整版 | 亚洲一级二级三级在线免费观看| 一区二区三区在线免费观看| 亚洲一区二区三区美女| 亚洲成a人在线观看| 五月天国产精品| 麻豆免费精品视频| 韩日精品视频一区| 国产精品综合久久| 成人精品高清在线| 色婷婷综合久久久中文字幕| 欧洲一区二区三区在线| 欧美肥妇free| 欧美精品一区二区三区在线| 国产亚洲精品资源在线26u| 色婷婷综合久色| 欧美丰满美乳xxx高潮www| 日韩免费在线观看| 国产精品色一区二区三区| 日韩美女啊v在线免费观看| 亚洲综合精品久久| 蜜臀av性久久久久蜜臀av麻豆| 国产麻豆欧美日韩一区| 99re这里只有精品视频首页| 欧美日韩一区二区三区在线看| 成人午夜av影视| 在线观看亚洲成人| 日韩一级成人av| 国产精品免费久久久久| 亚洲午夜精品网| 精品亚洲国产成人av制服丝袜| 成人小视频在线观看| 欧美日韩一区二区三区四区五区 | 天天色综合天天| 国产69精品久久久久毛片| 欧美视频一二三区| 久久久www免费人成精品| 亚洲蜜桃精久久久久久久| 奇米一区二区三区av| 成人精品电影在线观看| 91精品国产综合久久久久久久久久| 久久久久成人黄色影片| 亚洲第一二三四区| 欧美日韩一二三区| 久久久99精品免费观看| 亚洲国产精品视频| eeuss国产一区二区三区| 91精品国产综合久久精品麻豆| 国产欧美一区二区精品性色 | 8x8x8国产精品| 最新欧美精品一区二区三区| 精品一区二区免费看| 91蜜桃网址入口| 国产三级三级三级精品8ⅰ区| 五月天激情综合网| 91网站在线播放| 中文字幕国产一区| 精品无人码麻豆乱码1区2区| 欧美在线影院一区二区| 亚洲欧美在线另类| 国产一区二区伦理| 欧美成人免费网站| 视频一区二区不卡| 欧美丝袜丝nylons| 国产精品免费丝袜| 国产91精品在线观看| 久久久精品日韩欧美| 久久精品国产秦先生| 欧美一区二区三区性视频| 亚洲成在线观看| 欧美主播一区二区三区| 亚洲精品欧美激情| www.亚洲人| 日韩美女啊v在线免费观看| 成人美女视频在线看| 国产精品久久三区| 不卡在线观看av| 国产精品美女久久久久久2018|