Win32並行処理プログラミング入門23
CreateEventEx関数は、CreateEvent関数とほぼ同じです。第一パラメータはセキュリティ属性、第二パラメータはイベントの名前、第三パラメータはフラグ、第四パラメータはハンドルのアクセス権限です。違いはアクセス権限を設定できる点にあります。
CreateEvent関数で作られたハンドルは常にフルアクセスですが、CreateEventEx関数は権限を設定してハンドルを作れます。サンプルでは、SetEvent関数・ResetEvent関数・PulseEvent関数・同期用関数のアクセス権限を設定しています。なお、PulseEvent関数は、イベントをシグナル状態にした直後に、直ぐに非シグナル状態にする関数です。
アクセス権限の効果を確かめたい人は、Win32並行処理プログラミング入門21のサンプルを変更して下さい。
//CreateEventExの場合
hEvent = CreateEventEx(
0,
_T("piyo"),
CREATE_EVENT_MANUAL_RESET,
EVENT_MODIFY_STATE );
第四パラメータのSYNCHRONIZEを消して実行すると、WaitForSingleObject関数がエラーを返し、メッセージボックスにエラーが表示されます。このエラーは無視出来てしまう点に注意して下さい。戻り値を判定しないと、処理がそのまま進んでしまいます。試しにエラー処理を消してみて下さい。待機関数の意味がなくなり、処理が進んでしまうのが分かります。
//指定されたメッセージをコンソールへ出力し続ける関数
unsigned __stdcall MessageOutput( void* )
{
while( - 1 ) {
//データが初期化されるまで待つ
DWORD result = WaitForSingleObject( hEvent, INFINITE );
//エラーがあれば表示
/* ここから
if ( result == WAIT_FAILED ) {
LPVOID title = _T( "エラー" );
LPVOID msg;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
__nullptr,
GetLastError(),
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
reinterpret_cast< LPTSTR >( &msg ),
0,
__nullptr
);
MessageBox( __nullptr,
reinterpret_cast< LPCTSTR >( msg ) ,
reinterpret_cast< LPCTSTR >( title ),
MB_OK | MB_ICONERROR );
LocalFree( msg );
return -1;
}
ここまでコメントアウト*/
//データを出力
cout << msg.get_Message() << " ";
//出力スピードを遅くする
Sleep( 50 );
}
return 0;
}
これはWin32プログラミング全般に言える事ですが、エラーに十分な注意を払って下さい。エラー処理をするのが面倒で、CreateEventEx関数を使用したくない人が要るかもしれませんが、CreateEventEx関数の使用をお勧めします。Windowsはセキュリティが強化される方向でバージョンアップしています。アクセス権限を正しく設定した方が、将来のバージョンに対応できる可能性が高くなります。