亚洲欧美第一页_禁久久精品乱码_粉嫩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精品久久久久久9| 97精品久久久久中文字幕| 日韩欧美在线123| 亚洲成人精品一区二区| yourporn久久国产精品| www久久精品| 美女一区二区视频| 欧美日韩国产高清一区二区三区 | 欧美日韩在线播| 日本一区二区免费在线 | 久久精工是国产品牌吗| 欧美综合天天夜夜久久| 中文字幕免费不卡在线| 蜜臀av亚洲一区中文字幕| 欧美麻豆精品久久久久久| 亚洲欧美日韩电影| 99久久99久久综合| 国产精品久久99| 国产不卡视频一区二区三区| 亚洲精品一区二区三区在线观看 | 精品日韩欧美一区二区| 亚洲国产欧美一区二区三区丁香婷| 成人精品免费网站| 国产婷婷精品av在线| 国产精品一级黄| 26uuu国产在线精品一区二区| 美女被吸乳得到大胸91| 日韩一区二区三区免费看| 日韩福利视频网| 欧美精品九九99久久| 午夜精品一区二区三区三上悠亚| 欧美视频中文一区二区三区在线观看| 亚洲欧洲综合另类在线| 91丨porny丨中文| 亚洲精品乱码久久久久久久久| 91视频在线看| 亚洲亚洲精品在线观看| 欧美日韩中文一区| 日本美女一区二区| 精品国产一区二区亚洲人成毛片| 精品系列免费在线观看| 欧美高清在线精品一区| 97se亚洲国产综合自在线| 亚洲一区二区av在线| 91麻豆精品国产91久久久使用方法| 日本强好片久久久久久aaa| 欧美一区二区美女| 国产综合色视频| 亚洲欧洲性图库| 欧美日韩国产精品成人| 国产综合久久久久影院| 国产精品入口麻豆九色| 欧美性一级生活| 美女视频一区二区| 国产精品久久久久久久久久久免费看 | 亚洲午夜免费福利视频| 911国产精品| 国产精品影视网| 一区二区三区毛片| 日韩免费视频一区| 成a人片亚洲日本久久| 亚洲成av人片一区二区三区 | 蜜桃视频在线一区| 欧美国产一区在线| 欧美日韩aaaaaa| 国产精品一区二区久久精品爱涩| 国产精品国产馆在线真实露脸| 欧美视频一二三区| 国产91丝袜在线播放0| 一区二区在线观看免费视频播放| 久久久久九九视频| 色综合色综合色综合色综合色综合| 日韩成人伦理电影在线观看| 中文字幕精品—区二区四季| 欧美精品aⅴ在线视频| 国产91丝袜在线播放九色| 日日夜夜一区二区| 亚洲欧美色综合| 久久综合狠狠综合久久激情| 欧美在线观看视频一区二区三区| 精品无人码麻豆乱码1区2区| 亚洲一区二区三区在线| 国产日韩v精品一区二区| 777亚洲妇女| 色94色欧美sute亚洲13| 国产福利一区二区三区视频 | 婷婷激情综合网| 国产精品国产三级国产普通话蜜臀| 日韩一级免费一区| 91高清视频在线| 99久久精品免费| 国产成人综合网| 国产一区二区三区在线观看精品| 图片区日韩欧美亚洲| 亚洲自拍偷拍综合| 亚洲女厕所小便bbb| 亚洲国产激情av| 久久蜜桃av一区精品变态类天堂| 91精品国产色综合久久久蜜香臀| 欧美视频在线观看一区二区| 色婷婷久久一区二区三区麻豆| 成人深夜视频在线观看| 国产成人啪午夜精品网站男同| 看国产成人h片视频| 热久久国产精品| 蜜臀91精品一区二区三区| 日韩一区精品视频| 日韩中文字幕一区二区三区| 五月天激情小说综合| 亚洲在线观看免费| 亚洲成人午夜影院| 亚洲成人资源在线| 日日夜夜免费精品| 麻豆一区二区三| 精品系列免费在线观看| 国产一区激情在线| 国产精一区二区三区| 国产精华液一区二区三区| 国产激情一区二区三区四区 | 丰满少妇在线播放bd日韩电影| 国内一区二区在线| 国产经典欧美精品| aaa欧美色吧激情视频| 欧美三级一区二区| 欧美日韩一区不卡| 日韩欧美中文字幕公布| 久久久国产一区二区三区四区小说| 精品美女一区二区| 日本一区二区在线不卡| 亚洲欧美国产高清| 午夜精品久久久| 久久99精品网久久| 成人国产在线观看| 日本久久电影网| 日韩一级黄色大片| 国产亲近乱来精品视频| 国产精品国产三级国产三级人妇| 亚洲免费高清视频在线| 午夜av一区二区| 国产成人亚洲综合a∨猫咪| jizz一区二区| 欧美一区二区三区不卡| 精品999在线播放| 又紧又大又爽精品一区二区| 亚洲va韩国va欧美va| 国产精品一区二区免费不卡| 一本到三区不卡视频| 日韩免费观看高清完整版在线观看| 国产亚洲美州欧州综合国| 亚洲精品中文在线观看| 免费在线观看不卡| 色综合久久久网| 日韩午夜激情av| 亚洲免费观看在线视频| 久久er精品视频| 日本黄色一区二区| 久久综合九色综合97婷婷女人 | 日韩电影免费一区| 成人av网站在线观看免费| 欧美日韩高清在线| 欧美国产一区二区在线观看| 日本一道高清亚洲日美韩| 91丨九色丨蝌蚪富婆spa| 欧美va亚洲va香蕉在线| 亚洲综合色网站| 成人av在线播放网站| 日韩欧美成人激情| 亚洲国产精品尤物yw在线观看| 懂色av中文字幕一区二区三区 | 麻豆成人综合网| 91福利在线免费观看| 久久久久久久久岛国免费| 三级不卡在线观看| 欧美视频完全免费看| 亚洲色图19p| 91在线一区二区三区| 26uuu亚洲综合色| 日韩精品久久理论片| 欧美在线啊v一区| 亚洲免费伊人电影| 波多野结衣中文字幕一区二区三区 | 成人午夜在线免费| 久久综合视频网| 麻豆精品一区二区三区| 欧美日本精品一区二区三区| 亚洲激情av在线| 99免费精品视频| 国产精品麻豆网站| 成人午夜激情在线| 国产精品久久久久7777按摩 | 久久99国产精品免费网站| 69堂成人精品免费视频|