threadクラスの実装。その3-eventクラス-

condition variableのほうが一般的でしょうか?
とりあえずwindowsなので、イベントのラッパーを作ってみます。

eventクラス
#include <windows.h>

class event
{
    typedef HANDLE handle_t;
public:
    event( bool manual_reset, bool init_state )
    {
        handle = CreateEvent( 0, manual_reset ? TRUE : FALSE, init_state ? TRUE : FALSE, 0 );
        if( handle == 0 )throw "CreateEvent";
    }
protected:
    virtual ~event()
    {
        CloseHandle( handle );
    }

public:
    bool wait( unsigned long timeout = INFINITE )
    {
        return WaitForSingleObject( handle, timeout ) == WAIT_OBJECT_0;
    }

    void signal()
    {
        SetEvent( handle );
    }

    void nonsignal()
    {
        ResetEvent( handle );
    }

protected:
    handle_t handle;
};
manual_reset_eventクラス、auto_reset_eventクラス

C#っぽく、manual_reset_eventとauto_reset_eventを作っておくと便利かもしれません。

class manual_reset_event
    : public event
{
public:
    manual_reset_event( bool init_state )
        : event( true, init_state )
    {}
};


class auto_reset_event
    : public event
{
public:
    auto_reset_event( bool init_state )
        : event( false, init_state )
    {}
};
noncopyable

コピー禁止用コピーコンストラクタ、代入演算子の記述が面倒になってきたので、Non-copyable Mixinを使いましょう。

//コピーを禁止するクラスにprivate継承させる
class noncopyable
{
protected:
    noncopyable(){}
    ~noncopyable(){}

private:
    noncopyable( noncopyable const& );
    noncopyable& operator=( noncopyable const& );
};

使い方

auto_reset_event e( false );

void hoge()
{
    //イベントがシグナル状態になるまで待機
    e.wait();

    std::cout << "hoge" << std::endl;
}

struct piyo
{
    void operator()(){ std::cout << "piyo" << std::endl; }
};

int main()
{
    try
    {
        piyo p;
        thread_ptr t1 = new thread( &hoge );
        thread_ptr t2 = new thread( p );

        //適当な時間待って、イベントをシグナル状態にする
        Sleep( 5000 );
        e.signal();

        t1->join();
        t2->join();
    }
    catch( std::exception& e )
    {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

サンプル