2012-01-29 7 views
0

Мне нужно иметь класс с одним действием, которое выполняется один раз в 5 секунд в своей собственной ветке. Это веб-сервис, поэтому ему необходимо указать конечную точку. Во время выполнения объекта основной поток может изменить конечную точку. Это мой класс:объект промежуточного процесса

Следует ли объявлять новый объект newEndpoint изменчивым? Я бы, конечно, сделал это, если бы чтение было в некотором цикле (чтобы заставить компилятора не оптимизировать его), но здесь я не знаю.

В каждом запуске функция 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 методы.

Метод 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, а затем выполняете некоторую работу. Пока это происходит, ничто другое не может возиться с вашей конечной точкой, поскольку оно заблокировано мьютезом. Итак, в моем анализе и из того, что я вижу в вашем коде, эта переменная не обязательно изменяется достаточно.

Я не вижу сайт вызова вашего класса, поэтому я не знаю, используете ли вы один и тот же экземпляр класса 100 раз или более, или если вы создаете новые объекты.

Это тот анализ, который вам нужно сделать, когда спрашиваете, должно ли что-то быть volatile или нет.

Кроме того, на вашей безопасности потоков, что происходит в этих функциях:

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

Они используют любой из общего состояния с вашего Worker класса? Разделяют ли они и изменяют любое другое использование государством другим потоком?Если да, вам нужно выполнить соответствующую синхронизацию.

Если нет, тогда все в порядке.

Threading требует некоторого размышления, вам нужно задать себе эти вопросы. Вам нужно посмотреть на все состояние и задаться вопросом, используете ли вы. Если вы имеете дело с указателями, то вам нужно знать, кто владеет указателем, и независимо от того, используете ли вы его среди потоков случайно или нет, и действуйте соответствующим образом. Если вы передадите указатель на функцию, которая запускается в другом потоке, вы делитесь объектом, на который указывает указатель. Если вы затем измените то, на что указывает этот новый поток, вы делитесь и должны синхронизироваться.