2012-01-29 9 views
0

独自のスレッドで5秒に1回実行される1つのアクティビティを持つクラスが必要です。これはWebサービスのため、エンドポイントを指定する必要があります。オブジェクト実行時に、メインスレッドはエンドポイントを変更できます。これは私のクラスです:プロセス間オブジェクトの受け渡し

class Worker 
{ 
    public: 
    void setEndpoint(const std::string& endpoint); 

    private: 
    void activity (void); 

    mutex endpoint_mutex; 
    volatile std::auto_ptr<std::string> newEndpoint; 

    WebServiceClient client; 
} 

newEndpointオブジェクトはvolatile宣言する必要がありますか?私は確かに読んでいくつかのループ(コンパイラがそれを最適化しないようにするため)だったが、ここで私は知らない。

各実行では、新しいエンドポイント(新しいエンドポイントがある場合はそれをクライアントに渡して再接続手順を実行する)をチェックし、その作業を行います。

void Worker::activity(void) 
{ 
    endpoint_mutex.lock(); //don't consider exceptions 
    std::auto_ptr<std::string>& ep = const_cast<std::auto_ptr<string> >(newEndpoint); 
    if (NULL != ep.get()) 
    { 
     client.setEndpoint(*ep); 
     ep.reset(NULL); 
     endpoint_mutex.unlock(); 
     client.doReconnectionStuff(); 
     client.doReconnectionStuff2(); 
    } 
    else 
    { 
     endpoint_mutex.unlock(); 
    } 

    client.doSomeStuff(); 
    client.doAnotherStuff(); 
    ..... 
} 

IはnewEndpointオブジェクトがもはや変更できないので、私はCONSTメソッドを呼び出すことができるようにする揮発性クラス仕様を削除することを意味するミューテックスをロックします。 (別のスレッドから呼び出される)

setEndpoint方法:

void Worker::setEndpoint(const std::string& endpoint) 
{ 
    endpoint_mutex.lock(); //again - don't consider exceptions 
    std::auto_ptr<std::string>& ep = const_cast<std::auto_ptr<string> >(newEndpoint); 
    ep.reset(new std::string(endpoint); 
    endpoint_mutex.unlock(); 
} 

はこの事スレッドは安全ですか?そうでない場合は、何が問題なのですか?揮発性のnewEndpointオブジェクトが必要ですか?

答えて

1

volatileをMSDN当たり次の場合に使用される:

揮発性キーワードは 目的は、オペレーティング・システムのようなものによってプログラムで変更することができることを宣言するために使用されるタイプの修飾子であり、ハードウェア、または同時に実行しているスレッド。 それらの値はいつでもで変更することができますので、volatileとして宣言

オブジェクトは、特定の最適化 で使用されていません。システムは常に、以前の命令が同じオブジェクトから値を要求したとしても、要求された時点で揮発性オブジェクトの現在の値 を読み込みます。 また、オブジェクトの値は割り当て時にすぐに書き込まれます。

あなたの場合の質問は、実際にはあなたのNewEndPointは実際にどのくらいの頻度で変更されますか?あなたはスレッドAで接続を作成し、次に作業を行います。これが進んでいる間、mutexによってロックされているので、あなたのエンドポイントを操作することはできません。だから、私の分析と私はあなたのコードで見ることができますから、この変数は必ずしも十分に変更されていません。

クラスのコールサイトが表示されないため、同じクラスインスタンスを100回以上使用しているのか、新しいオブジェクトを作成しているのか分かりません。

これは、何かがvolatileであるかどうかを尋ねるときに行う必要がある分析の種類です。

また、あなたのスレッドの安全性について、何がこれらの機能に起こる:

client.doReconnectionStuff(); 
client.doReconnectionStuff2(); 

彼らはあなたのWorkerクラスから共有状態のいずれかを使用していますか?他のスレッドによる他の州の使用を共有したり変更したりしていますか?はいの場合は、適切な同期を行う必要があります。

もしそうでなければ、あなたは大丈夫です。

スレッディングにはいくつかの考えが必要です。これらの質問を自分で行う必要があります。あなたはすべての州を見て、あなたが共有しているかどうか疑問に思う必要があります。あなたがポインタを扱っているなら、あなたはポインタを所有しているのかどうか、またスレッド間でそれを偶然に共有しているのかどうか、それに応じて行動するのかどうかが不思議です。別のスレッドで実行されている関数へのポインタを渡すと、ポインタが指すオブジェクトを共有しています。この新しいスレッドで指しているものを変更すると、共有していて同期する必要があります。

関連する問題