独自のスレッドで 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 と宣言する必要がありますか? 読み取りが何らかのループにある場合(コンパイラーが最適化しないようにするため)は確かにそれを行いますが、ここではわかりません。
実行ごとに、activity()
関数は新しいエンドポイントをチェックし (新しいエンドポイントがある場合は、それをクライアントに渡し、いくつかの再接続手順を実行します)、その作業を行います。
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();
.....
}
ミューテックスをロックします。つまり、newEndpoint オブジェクトは変更できなくなります。そのため、constメソッドを呼び出せるようにvolatileクラスの仕様を削除します。
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 オブジェクトを揮発性にする必要がありますか?