Windows API(二)プロセス

14655 ワード

Windows APIノート(一)カーネルオブジェクトWindows APIノート(二)プロセスとプロセス間通信、プロセス境界Windows APIノート(三)スレッドとスレッド同期、スレッドローカルストレージWindows APIノート(四)win 32メモリ構造Windows APIノート(五)仮想メモリWindows APIノート(六)メモリマッピングファイルWindows APIノート(七)スタックWindows APIノート(八)ファイルシステムWindows APIノート(九)ウィンドウメッセージWindows APIノート(十)動的リンクライブラリWindows APIノート(十一)設備I/O
文書ディレクトリ
  • 1. Win 32アプリケーション
  • 1.1プロセスのハンドル
  • 1.2プロセスの環境変数
  • 1.3プロセスのエラーモード
  • 1.4プロセスの現在のドライブとディレクトリ
  • 1.5システムバージョン
  • 2. CreateProcess関数
  • 3. プロセス終了
  • 4. サブプロセス
  • 4.1分離されたサブプロセスを実行する
  • 5. プロセス間通信
  • プロセスは、アプリケーションの実行インスタンスとして定義されることが多い.Win 32では、各プロセスに4 GBのアドレス空間がある.プロセスは不活性であり、Win 32プロセスは何も実行されず、アプリケーションに必要なバイナリコードとデータを格納するために4 GBのアドレス空間を持っているだけです.
    アドレス空間に加えて、各プログラムにはファイル、ダイナミックメモリ割り当て、スレッドなどの別のリソースがあります.これらの異なるリソースは、プロセスの生命の中で作成され、プロセスが終了すると解放されます.
    各スレッドには独自のCPUレジスタグループとスタックがあります.オペレーティングシステムは独立したスレッドごとにCPUの時間スケジューリングを行い、オペレーティングシステムはローテーション方式でスレッドにタイムスライスを提供する.
    1.Win 32アプリケーション
    システムのローダは、アプリケーションがCUIベースかGUIベースかに関心を持ち、exeファイルにCUIベースのアプリケーションが指定されている場合、ローダは自動的にそのプログラムのコンソールウィンドウを生成します.
    1.1プロセスのハンドル
    プロセスアドレス空間にロードされるexeファイルまたはdllファイルごとに、一意のインスタンスハンドルがあります.exeファイルの例はWinMainの最初のパラメータhinstExeとして渡され、リソースをロードする関数を呼び出すときに通常このハンドルの値が必要です.
    1.2プロセスの環境変数
    各プロセスには、関連する環境ブロックがあります.環境ブロックは、プロセスのアドレス空間に割り当てられたメモリです.一般的なサブプロセスは、親プロセスから完全に同じ環境変数のセットを継承します.ただし、親プロセスは、子プロセスが継承する変数(CreateProcessのパラメータ設定)を制御します.環境変数はGetEnvironmentVariableとSetEnvironmentVariableで取得および設定できます.
    1.3プロセスのエラーモード
    各プロセスには、重大なエラーにどのように反応するかを示すフラグのセットがあります.プロセスは、SetErrorMode関数を呼び出し、各エラーをどのように処理するかをシステムに伝えることができます.
    ひょうしき

    説明
    SEM_FAILCRITICALERRORS
    0x0001
    システムは重大なエラー処理メッセージボックスを表示せず、エラーを呼び出したプロセスに返します.
    SEM_NOGPFAULTERRORBOX
    0x0002
    システムは通常保護エラーメッセージボックスを表示せず、このフラグはデバッグアプリケーション設定によってのみ通常保護(GP)エラーを異常ハンドルで自分で処理できる
    SEM_NOALIGNMENTFAULTEXCEPT
    0x0004
    ファイルが見つからない場合、システムは現実的ではありません.
    SEM_NOOPENFILEERRORBOX
    0x8000
    システムはメモリ並べ替えエラーを自動的に修正し、アプリケーションに表示されないようにします.このフラグはx 86またはAlphaプロセッサには機能しません.
    デフォルトでは、子プロセスは親プロセスのエラーモードを継承します.CreateProcessで設定を継承しないようにすることもできます.
    1.4プロセスの現在のドライブとディレクトリ
    環境変数で設定可能
    1.5システムバージョン
    //      ,           
    DWORD GetVersion(void)
    
    //    
    BOOL GetVersionEx(LPOSVERSIONINFOA lpVersionInformation);
    
    	
        printf("%X 
    "
    , GetVersion()); OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof(osv); BOOL ret = GetVersionEx(&osv); if (ret) { printf("%X - %X - %X - %X - %s
    "
    , osv.dwMajorVersion, // osv.dwMinorVersion, // osv.dwBuildNumber, // osv.dwPlatformId, // osv.szCSDVersion); } else { perror("GetVersionEx Error"); }

    2.CreateProcess関数
    BOOL CreateProcess(
        _In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOA lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation
        );
    
    

    3.プロセスの終了
  • プロセス中にあるスレッドがExitProcess関数
  • を呼び出す.
  • プロセスのスレッドがTerminateProcess関数(現在のプロセスを終了するか、他のプロセスを殺すか)
  • を呼び出した.
    メインスレッドでreturnとExitProcessおよびTerminateProcessを使用するのはどのような違いがありますか?参考:『Windowsでのreturn,exitとExitProcessの違いと分析--』
    プロセス内のすべてのスレッドが終了すると、自動的にプロセスが終了します(ExitThread、TerminateThread).
    プロセスが終了すると、次のことが起こります.
  • 残りのすべてのスレッドは
  • で終了する.
  • プロセスで割り当てられたメモリは解放する(スレッド割り当ては解放されない可能性がある)、すべてのカーネルオブジェクトは
  • を閉じる.
  • プロセス内のカーネルオブジェクトの状態は、信号状態(WaitForSingleObjectは戻り値を得る)
  • となる.
  • プロセスの終了コードは、STILL、ACTIVEからExitProcessまたはTerminateProcessによって伝達するコード
  • となる.
  • プロセスカーネルオブジェクトの使用数は-1(プロセスカーネルオブジェクトは必ずしも0になるとは限らず、すべての参照プロセス呼び出しCloseHandleまたはプロセスクローズ、またはGetExitCodeProcessを呼び出す必要がある)
  • である.
    4.サブプロセス
    新しいスレッドを作成し、結果を待ちます.
            STARTUPINFO si;
            memset(&si, 0, sizeof(STARTUPINFO)); //   si       
            si.cb = sizeof(STARTUPINFO);
            si.dwFlags = STARTF_USESHOWWINDOW;
            si.wShowWindow = TRUE;
    
            PROCESS_INFORMATION pi;
            ZeroMemory(&pi, sizeof(pi));
    
    		DWORD dwExitCode;
    
            char exec_file[] = TEXT("kernel_handle_inherit.exe"); //
    
            if (!CreateProcess(exec_file, //    
                               cmd,       //     
                               NULL,
                               NULL,
                               TRUE,               //         
                               CREATE_NEW_CONSOLE, //                
                               NULL,
                               NULL,
                               &si,
                               &pi))
            {
                perror("CreateProcess Error");
                exit(1);
            }
            else
            {
            	//           
                ::CloseHandle(pi.hThread);
                
                //        
                WaitForSingleObject(pi.hProcess, INFINITE);
                
                //      
                GetExitCodeProcess(pi.hProcess,&dwExitCode);
                
                //      ,    -1,          
                ::CloseHandle(pi.hProcess);
            }
    

    4.1分離されたサブプロセスの実行
    サブプロセスのクローズを待たない:
    		PROCESS_INFORMATION pi;
            if (!CreateProcess(,,,&pi))
            {
                perror("CreateProcess Error");
                exit(1);
            }
            else
            {
            	//           
                ::CloseHandle(pi.hThread);
                //      ,    -1,             (         )
                ::CloseHandle(pi.hProcess);
            }
    

    5.プロセス間通信
    Interprocess Communications