java 线程句柄_等待Windows线程中的句柄

当进程结束时,您可以使用RegisterWaitForSingleObject()通过回调获得通知 . RegisterWaitForSingleObject 函数指示thread pool中的等待线程等待进程,因此这应该是资源的最佳使用 . 正如Raymond Chen评论的那样:

线程池可以将多个Wait请求批处理为对WaitForMultipleObjects的单个调用,因此摊销成本是线程的1/63 .

下面是Win32 GUI应用程序的最小示例 . 代码创建一个窗口,然后它创建自己的另一个实例作为子进程,由"/child"参数指示 . 它注册等待回调函数并运行常规消息循环 . 您可以调整窗口大小并移动窗口以查看GUI未被阻止 . 当子进程结束时,系统异步调用等待回调,该回调将应用程序定义的消息( WM_APP )发布到窗口 . 当窗口收到消息时,它立即调用 UnregisterWait() 取消等待 . 作为参考状态,在等待完成时必须取消使用 WT_EXECUTEONLYONCE 的等待操作(但不是在回调中!) . 然后窗口显示一个消息框,以证明它已收到消息 .

为简洁起见,省略了错误处理 . 您应检查每个API函数的返回值,并在返回 FALSE 时调用 GetLastError() .

#pragma comment(linker, "/SubSystem:Windows")

#include

#include

int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPWSTR lpCmdLine, int /*nCmdShow*/ )

{

if ( wcsstr( lpCmdLine, L"/child" ) )

{

MessageBoxW( nullptr, L"Hello from child process!", L"Child", MB_OK );

return 0;

}

// Create window

struct WindowData

{

HANDLE hWait = nullptr;

}

wndData;

WNDCLASSW wc{};

wc.hInstance = hInstance;

wc.hCursor = LoadCursor( nullptr, IDC_ARROW );

wc.hbrBackground = reinterpret_cast(GetStockObject( WHITE_BRUSH ));

wc.lpszClassName = L"MyClass";

wc.cbWndExtra = sizeof(LONG_PTR);

wc.lpfnWndProc = []( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )

{

switch ( message )

{

case WM_APP:

{

// When the wait is completed, you must call the UnregisterWait or UnregisterWaitEx function to cancel

// the wait operation. (Even wait operations that use WT_EXECUTEONLYONCE must be canceled.)

WindowData* pWndData = reinterpret_cast(GetWindowLongPtr( hWnd, 0 ));

UnregisterWait( pWndData->hWait );

pWndData->hWait = nullptr;

MessageBoxW( hWnd, L"Child process has ended!", L"Main", MB_OK );

}

break;

case WM_DESTROY:

PostQuitMessage( 0 );

break;

}

return DefWindowProc( hWnd, message, wParam, lParam );

};

RegisterClassW( &wc );

HWND hWnd = CreateWindowExW( 0, wc.lpszClassName, L"Main", WS_OVERLAPPEDWINDOW | WS_VISIBLE,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr );

SetWindowLongPtr( hWnd, 0, reinterpret_cast( &wndData) );

// Create child process

std::wstring cmd( MAX_PATH, L'\0' );

cmd.resize( GetModuleFileNameW( nullptr, &cmd[0], cmd.size() ) );

cmd = L"\"" + cmd + L"\" /child";

STARTUPINFOW si{ sizeof( si ) };

PROCESS_INFORMATION pi{};

CreateProcessW( nullptr, &cmd[0], nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi );

// Get notified when child process ends

RegisterWaitForSingleObject( &wndData.hWait, pi.hProcess,

[]( PVOID lpParameter, BOOLEAN /*TimerOrWaitFired*/ )

{

PostMessage( reinterpret_cast(lpParameter), WM_APP, 0, 0 );

},

reinterpret_cast(hWnd), INFINITE, WT_EXECUTEONLYONCE );

// Run message loop

MSG msg;

while ( GetMessage( &msg, nullptr, 0, 0 ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

// Cleanup

if( wndData.hWait )

UnregisterWait( wndData.hWait );

if( pi.hProcess )

CloseHandle( pi.hProcess );

if( pi.hThread )

CloseHandle( pi.hThread );

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值