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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

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

?? 漫談系統(tǒng)內(nèi)核內(nèi)幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 5 頁
字號:
    /* Check for Success and release if such */
    if(NT_SUCCESS(Status)) {
       
        LONG Prev;
       
        /* Save the Old State */
        DPRINT("Releasing Mutant\n");
        Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, FALSE, FALSE);
        ObDereferenceObject(Mutant);

        /* Return it */       
        if(PreviousCount) {
            _SEH_TRY . . . . . . _SEH_END;
        }
    }
    /* Return Status */
    return Status;
}[/code]
    顯然,這里實質(zhì)性的操作是KeReleaseMutant(),我們順著往下看。

[code][NtReleaseMutant() > KeReleaseMutant()]

LONG
STDCALL
KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment,
                IN BOOLEAN Abandon, IN BOOLEAN Wait)
{
    KIRQL OldIrql;
    LONG PreviousState;
    PKTHREAD CurrentThread = KeGetCurrentThread();
   
    /* Lock the Dispatcher Database */
    OldIrql = KeAcquireDispatcherDatabaseLock();
   
    /* Save the Previous State */
    PreviousState = Mutant->Header.SignalState;
   
    /* Check if it is to be abandonned */
    if (Abandon == FALSE) {
        /* Make sure that the Owner Thread is the current Thread */
        if (Mutant->OwnerThread != CurrentThread) {
            DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
            ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
        }
        /* If the thread owns it, then increase the signal state */
        Mutant->Header.SignalState++;
    } else  {
        /* It's going to be abandonned */
        DPRINT("Abandonning the Mutant\n");
        Mutant->Header.SignalState = 1;
        Mutant->Abandoned = TRUE;
    }
   
    /* Check if the signal state is only single */
    if (Mutant->Header.SignalState == 1) {
        if (PreviousState <= 0) {
            DPRINT("Removing Mutant\n");
            RemoveEntryList(&Mutant->MutantListEntry);
        }
        /* Remove the Owning Thread and wake it */
        Mutant->OwnerThread = NULL;
        /* Check if the Wait List isn't empty */
        DPRINT("Checking whether to wake the Mutant\n");
        if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
            /* Wake the Mutant */
            DPRINT("Waking the Mutant\n");
            KiWaitTest(&Mutant->Header, Increment);
        }
    }

    /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
    if (Wait == FALSE) {
        /* Release the Lock */
        KeReleaseDispatcherDatabaseLock(OldIrql);
    } else {
        /* Set a wait */
        CurrentThread->WaitNext = TRUE;
        CurrentThread->WaitIrql = OldIrql;
    }
    /* Return the previous state */
    return PreviousState;
}[/code]
    參數(shù)Abandon表示在退出臨界區(qū)以后是否要廢棄這個互斥門。我們從NtReleaseMutant()的代碼中可以看出,實際傳下來的參數(shù)值是FALSE。那么什么情況下這個參數(shù)會是TRUE呢?據(jù)“Native API”書中說,這發(fā)生于互斥門的業(yè)主、就是已經(jīng)通過這個互斥門進入了臨界區(qū)的線程突然要結(jié)束其生命的時候。
    既然臨界區(qū)中的線程要退出,這個互斥門就變成無主的了,所以把Mutant->OwnerThread設(shè)置成NULL。其余的代碼就留給讀者自己去理解了。

4. 事件(Event)

    信號量機制的另一個變種是“事件”,這是通過事件對象實現(xiàn)的。Windows為事件對象的創(chuàng)建和打開提供了NtCreateEvent()和NtOpenEvent()兩個系統(tǒng)調(diào)用。由于所有此類函數(shù)的相似性,這兩個系統(tǒng)調(diào)用的代碼就不用看了,只要知道內(nèi)核中代表著事件對象的數(shù)據(jù)結(jié)構(gòu)是KEVENT就可以了:

[code]typedef struct _KEVENT {
  DISPATCHER_HEADER  Header;
} KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT;[/code]

    這就是說,除DISPATCHER_HEADER以外,KEVENT就不需要有別的什么字段了。
    Windows定義和提供了兩種不同類型的事件,每個事件對象也因此而分成兩種類型,這就是:

[code]typedef enum _EVENT_TYPE {
  NotificationEvent,
  SynchronizationEvent
} EVENT_TYPE;[/code]
    事件對象的類型是在創(chuàng)建的時候(通過參數(shù))設(shè)定的,記錄在對象頭部的Type字段中,設(shè)定以后就不能改變。為不同的應(yīng)用和目的需要使用不同類型的事件對象。
    類型為NotificationEvent的事件代表著“通知”。通知是廣播式的,其作用就是通知公眾某個事件業(yè)已發(fā)生(Header中的SignalState為1),一個觀看者看了這個布告并不影響別的觀看者繼續(xù)觀看。所以,在通知型事件對象上的P操作并不消耗資源,也就是不改變其數(shù)值。在這一點上它就像是一個全局(跨進程)的變量。但是,如果事件尚未發(fā)生(SignalState為0),則所有的觀看者、即對此對象執(zhí)行P操作的線程全都被阻塞而進入睡眠,直到該事件發(fā)生,在這一點上又不太像“通知”,而反倒是起著同步的作用了(設(shè)想你去看高考發(fā)榜,但是還沒貼出來,你就被“套住”等在那兒了)。讀者也許會想到,既然P操作不改變SignalState的值,那豈不是一旦SignalState變成1就永遠是1、從而事件對象只能一次性使用了?這確實是個問題,所以Windows又專門提供了一個系統(tǒng)調(diào)用NtResetEvent(),用來“重啟(Reset)”一個事件對象、即將其SignalState清0。
    類型為SynchronizationEvent的事件對象則用于同步,這就相當于初值為0、最大值為1的信號量。對于同步型的事件對象,一次P操作相當于消耗一個籌碼(通行證),而V操作則相當于提供一個籌碼。
    回顧一下前面KiIsObjectSignaled()的代碼,這是P操作中用來判斷是否可以(拿到籌碼)進入臨界區(qū)的函數(shù)。這個函數(shù)對于除互斥門以外的所有對象都返回(!Object->SignalState <= 0)。這就是說,不管是同步型還是通知型的事件對象,執(zhí)行P操作的線程能拿到籌碼或看到通知的條件都是SignalState為1,否則就要睡眠等待。
    再回顧一下KiSatisfyObjectWait()的代碼,這是P操作中拿到籌碼以后的操作:

[code]KiSatisfyObjectWait(PDISPATCHER_HEADER Object, PKTHREAD Thread)
{
    /* Special case for Mutants */
    if (Object->Type == MutantObject) {
        . . . . . .
    } else if ((Object->Type & TIMER_OR_EVENT_TYPE) == EventSynchronizationObject) {
        /* These guys (Syncronization Timers and Events) just get un-signaled */
        Object->SignalState = 0;
    } else if (Object->Type == SemaphoreObject) {
        /* These ones can have multiple signalings, so we only decrease it */
        Object->SignalState--;
    }
}[/code]

    這里Object->Type的最低3位記錄著對象的類型,如果是EventSynchronizationObject就說明是同步型的事件對象,此時把Object->SignalState置0,表示把籌碼消耗掉了。由于事件對象的SignalState只有兩個值0或非0,因而在SignalState為1的條件下將其設(shè)置成0跟使之遞減是等價的。可是,如果是通知型的事件對象,那就沒有任何操作,所以并沒有把通知“消耗”掉。所以,這又是變相的P操作。
    跟信號量和互斥門一樣,對事件對象的P操作就是系統(tǒng)調(diào)用NtWaitForSingleObject()或NtWaitForMultipleObjects(),或者(如果從內(nèi)核中調(diào)用)也可以是KeWaitForSingleObject(),而KiIsObjectSignaled()和KiSatisfyObjectWait()都是在P操作內(nèi)部調(diào)用的函數(shù)。

    事件對象的V操作是系統(tǒng)調(diào)用NtSetEvent(),意思是把事件對象的SignalState設(shè)置成1。就像NtReleaseMutant()的主體是KeReleaseMutant()一樣,NtSetEvent()的主體是KeSetEvent()。我們跳過NtSetEvent()這一層,直接看KeSetEvent()的代碼。

[code][NtSetEvent() > KeSetEvent()]

LONG  STDCALL
KeSetEvent(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait)
{
    . . . . . .
    /* Lock the Dispathcer Database */
    OldIrql = KeAcquireDispatcherDatabaseLock();
    /* Save the Previous State */
    PreviousState = Event->Header.SignalState;
   
    /* Check if we have stuff in the Wait Queue */
    if (IsListEmpty(&Event->Header.WaitListHead)) {
        /* Set the Event to Signaled */
        DPRINT("Empty Wait Queue, Signal the Event\n");
        Event->Header.SignalState = 1;
    } else {
        /* Get the Wait Block */
        WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
                                            KWAIT_BLOCK, WaitListEntry);
        /* Check the type of event */
        if (Event->Header.Type == NotificationEvent || WaitBlock->WaitType == WaitAll) {
            if (PreviousState == 0) {
                /* We must do a full wait satisfaction */
                DPRINT("Notification Event or WaitAll, Wait on the Event and Signal\n");
                Event->Header.SignalState = 1;
                KiWaitTest(&Event->Header, Increment);
            }
        } else {
           /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */
            DPRINT("WaitAny or Sync Event, just unwait the thread\n");
            KiAbortWaitThread(WaitBlock->Thread, WaitBlock->WaitKey, Increment);
        }
    }
   
    /* Check what wait state was requested */
    if (Wait == FALSE) {
        /* Wait not requested, release Dispatcher Database and return */   

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
777午夜精品视频在线播放| 久久免费的精品国产v∧| 日韩一区二区电影在线| 国产欧美一区二区在线观看| 自拍偷拍欧美激情| 经典三级视频一区| 欧美亚日韩国产aⅴ精品中极品| 欧美一级艳片视频免费观看| 亚洲人成网站精品片在线观看 | 欧美r级在线观看| 亚洲色图视频网站| 国产一区二区0| 欧美精品vⅰdeose4hd| 中文字幕一区二区三| 老司机精品视频导航| 欧美图片一区二区三区| 国产精品人成在线观看免费 | 亚洲国产高清在线| 中文字幕日本乱码精品影院| 欧美日韩精品综合在线| 7777精品伊人久久久大香线蕉| 国产精品毛片大码女人| 久久精品国产一区二区| 欧美天堂亚洲电影院在线播放| 国产精品入口麻豆九色| 国产一区二区精品久久91| 91精品国产麻豆| 亚洲高清一区二区三区| 欧美午夜电影网| 玉足女爽爽91| 欧美综合天天夜夜久久| 亚洲乱码日产精品bd| 99久久国产综合色|国产精品| 国产日韩综合av| 国产一区二区调教| 国产亚洲一二三区| 国产精品99久久不卡二区| 欧美成人一区二区三区片免费| 日韩高清在线不卡| 91精品视频网| 久久精品久久99精品久久| 欧美电影精品一区二区| 久久99国产精品久久| 精品处破学生在线二十三| 久久成人羞羞网站| 久久青草欧美一区二区三区| 国产乱人伦偷精品视频不卡| 久久精品视频一区二区| 处破女av一区二区| 自拍偷拍国产精品| 在线观看视频一区二区欧美日韩| 夜夜嗨av一区二区三区四季av| 在线看日韩精品电影| 亚洲电影视频在线| 日韩欧美国产午夜精品| 国内精品国产成人| 成人欧美一区二区三区1314| 色噜噜久久综合| 日韩av在线免费观看不卡| 欧美一二三区在线| 国产精品18久久久久久vr| 欧美国产精品一区| 欧美午夜精品久久久| 国产剧情av麻豆香蕉精品| 亚洲三级视频在线观看| 欧美日韩aaa| 国产一区二区三区在线观看精品| 国产精品久久网站| 欧美精品日韩一本| 国产.欧美.日韩| 一区二区三区在线观看动漫| 91精品国产高清一区二区三区| 国产精品一区二区黑丝| 亚洲欧美另类小说| 日韩欧美激情四射| 99久久久久久| 美女脱光内衣内裤视频久久网站 | 一区二区三区四区中文字幕| 91麻豆精品国产91久久久使用方法 | 欧美成人高清电影在线| 大美女一区二区三区| 午夜精品一区二区三区电影天堂 | 久久香蕉国产线看观看99| 不卡av在线免费观看| 理论片日本一区| 一区二区三区精品| 欧美经典一区二区| 制服丝袜激情欧洲亚洲| 99精品黄色片免费大全| 狠狠v欧美v日韩v亚洲ⅴ| 亚洲最快最全在线视频| 国产女人18水真多18精品一级做 | 亚洲一区二区三区视频在线播放| 久久久国际精品| 欧美久久久久久久久久| 99久久国产综合色|国产精品| 久久99精品久久久| 亚洲妇熟xx妇色黄| 亚洲免费伊人电影| 国产色综合一区| 日韩免费视频一区二区| 欧美日本高清视频在线观看| 色综合久久中文字幕| 在线观看欧美日本| 91免费观看在线| www.亚洲色图.com| 成人性生交大片免费| 精品一区二区久久久| 天天免费综合色| 一区二区三区鲁丝不卡| 亚洲人成网站色在线观看| 国产精品视频一二| 久久久噜噜噜久噜久久综合| 日韩欧美在线一区二区三区| 欧美色网站导航| 欧美性猛片aaaaaaa做受| 色综合色综合色综合| 不卡免费追剧大全电视剧网站| 国产精品一二三四| 国产白丝网站精品污在线入口| 狠狠色丁香婷婷综合久久片| 久久成人综合网| 国内成+人亚洲+欧美+综合在线| 免费高清在线一区| 奇米影视在线99精品| 美国十次了思思久久精品导航| 免费高清在线一区| 精品一区二区三区免费毛片爱| 狠狠色丁香婷综合久久| 国产91丝袜在线播放九色| 国产乱国产乱300精品| 成人中文字幕在线| 91碰在线视频| 欧美日韩亚洲综合在线 | 久久亚洲免费视频| 国产精品无人区| 一区二区三区国产豹纹内裤在线| 伊人一区二区三区| 爽好久久久欧美精品| 美日韩一区二区| 国产精品亚洲成人| 色偷偷成人一区二区三区91| 欧美在线三级电影| 91精品国产综合久久久久久久| 欧美一级xxx| 国产精品久久久久永久免费观看| 亚洲欧美激情一区二区| 五月天中文字幕一区二区| 麻豆精品一区二区三区| 粉嫩av一区二区三区| 色吊一区二区三区| 91精品国产色综合久久不卡电影| 精品国产乱码久久久久久1区2区| 国产精品视频yy9299一区| 亚洲黄色录像片| 久久成人麻豆午夜电影| 99久久综合精品| 欧美一区二区视频免费观看| 久久综合视频网| 伊人色综合久久天天| 美国十次了思思久久精品导航| 成人高清视频免费观看| 在线电影一区二区三区| 国产精品夫妻自拍| 欧美aaa在线| 91免费精品国自产拍在线不卡 | 亚洲国产精品自拍| 国产精品资源在线看| 精品视频一区三区九区| 国产日韩欧美综合在线| 五月天激情综合网| 91免费国产视频网站| 26uuu亚洲综合色| 亚洲图片欧美综合| 欧美精选一区二区| 亚洲乱码国产乱码精品精98午夜| 久久国内精品自在自线400部| 色综合久久88色综合天天6| 久久免费午夜影院| 秋霞午夜鲁丝一区二区老狼| 色妞www精品视频| 欧美国产国产综合| 国产一区二区伦理片| 91精品国产综合久久久久久久| 亚洲免费在线播放| 97国产一区二区| 国产三级精品三级| 国产在线视视频有精品| 欧美一个色资源| 日韩中文字幕1| 欧美日韩一卡二卡| 亚洲黄一区二区三区| 91视视频在线观看入口直接观看www| 日韩欧美一区二区免费| 天堂久久一区二区三区| 在线观看视频欧美| 亚洲一区二区三区四区不卡| 91亚洲国产成人精品一区二区三| 久久精品一区二区三区不卡| 久久99久久99小草精品免视看|