FC2ブログ

[Development][VC++] 意図的にデッドロックを発生させる

 変なコードですが、擬似的な親子二つのプロセスを立ち上げて、一方が他方のプロセスを監視しています(実際にプロセス間に親子関係があるわけではありません)。
 先に疑似親プロセスを起動し、続いて疑似子プロセスを起動します。
 疑似親子プロセスの間で意図的にデッドロックを発生させています。そのため、疑似子プロセスが消滅(このままだとCTRL+Cなどで意図的に停止しないといけませんが)すると、デッドロック状態が解消され疑似親プロセスも正常終了します。

 これら二つのプロセスはどちらも同じ実行ファイルから起動します。疑似親プロセスの起動には/pスイッチを使用して、疑似子プロセスの起動には/cスイッチを使用します。

 これだけではほとんど意味はありませんが、常時疑似子プロセスを監視して、疑似子プロセスが消滅した時点で疑似親プロセスに何らかの処理をさせることができます。(こういう場合、ふつうはプロセスのハンドルを取得すると思いますがね・笑)

 最後に、疑似親プロセスが、500msecごとにWaitをLoopさせていますが、疑似子プロセスがミューテックスハンドルを握り込んだまま消滅するとオブジェクトの状態が怪しくなるためです。当初は疑似子プロセスが終了したところでWAIT_ABANDONEDが返ってくると予想していたのですが、私がタメしたXP SP3上ではそのまま疑似親プロセスがロックされていました。

 ふつうはシステムオブジェクトをロックしたままプロセスを終了させるような凶悪なことはせず、この場合は疑似子プロセスのプロセスハンドルをWaitすると思います。その場合、疑似子プロセスが終了したところでロックが解除され、WAIT_OBJECT_0が返ってくるでしょう。

#include <windows.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
    bool    bParent=false;
    bool    bChild=false;
    int     idx=1;
    HANDLE  hMutex[2]={INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};


    __try{
        while(idx<argc)
        {
            if(strncmp(argv[idx],"/p",2)==0)    //  parent process
            {
                bParent=true;
            } else if (strncmp(argv[idx],"/c",2)==0)    //  child process
            {
                bChild=true;
            } else
            {
                printf("parameter <%s> is invalid.\n\0", argv[idx]);
            }

            idx++;
        }

        if(bParent&&bChild)
        {
            printf("Parameter \"/p\" and \"/c\" is alternative.\n\0");
        } else if(bParent)
        {
            hMutex[0]=::CreateMutex(NULL,TRUE,"Global\\SampleMutex_Parent\0");

            do{
                ::Sleep(500);
                hMutex[1]=::OpenMutex(MUTEX_ALL_ACCESS,FALSE,"Global\\SampleMutex_Child\0");
            } while(hMutex[1]==NULL);

            while(::WaitForSingleObject(hMutex[1],500)==WAIT_TIMEOUT)
            {
                printf(".\0");
            }
            printf("\n\0");

            printf("Parent process end.\n\0");
        } else if(bChild)
        {
            hMutex[0]=::OpenMutex(MUTEX_ALL_ACCESS,FALSE,"Global\\SampleMutex_Parent\0");
            hMutex[1]=::CreateMutex(NULL,TRUE,"Global\\SampleMutex_Child\0");
            ::WaitForSingleObject(hMutex[0],INFINITE);

            printf("Child process end.\n\0");    //  これ以降は通過しない

        }
    }
    __finally
    {
        printf("Finalize procedure...\n\0");

        if( hMutex[0]!=NULL                    ||
            hMutex[0]!=INVALID_HANDLE_VALUE    )
        {
            ::CloseHandle(hMutex[0]);
        }
        if( hMutex[1]!=NULL                    ||
            hMutex[1]!=INVALID_HANDLE_VALUE    )
        {
            ::CloseHandle(hMutex[1]);
        }
    }

    return 0;
}
スポンサーサイト



FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

comment

管理者にだけメッセージを送る

カレンダー
11 | 2019/12 | 01
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
最近の記事
月別アーカイブ
カテゴリー
ブログ内検索
RSSフィード
リンク
いろいろリンクボタン
埋め込みe-Words