2015-08-23 2 views
0

Я хочу создать интерфейс контура управления.Является ли этот интерфейс потокобезопасным?

У этого метода есть should_stop() метод проверки, должен ли цикл прерываться или продолжать.

Он прослушивает сигнал SIGINT (Ctrl + C) и после получения сигнала should_stop() метод возвращает True.

Теперь кажется, что этот интерфейс работает.

Но я не уверен, что этот интерфейс является потокобезопасным.

LoopInterface.h файл

#include "signal.h" 
#include "pthread.h" 

#define LOCK(mutex)  pthread_mutex_lock(&mutex) 
#define UNLOCK(mutex) pthread_mutex_unlock(&mutex) 

class LoopInterface { 
public: 
    LoopInterface(){ 
     LOCK(_lock_is_signal_registered); 
     bool temp = _is_signal_registered; 
     UNLOCK(_lock_is_signal_registered); 
     if(!temp) 
     { 
      register_signal(); 
     } 
    } 

    bool should_stop() 
    { 
     LOCK(_lock_should_stop); 
     bool temp = _should_stop; 
     UNLOCK(_lock_should_stop); 
     return _should_stop; 
    } 

private: 

    static void register_signal() 
    { 
     LOCK(_lock_is_signal_registered); 
     _is_signal_registered = true; 
     UNLOCK(_lock_is_signal_registered); 

     signal(SIGINT, &LoopInterface::signal_handler); 
    } 

    static void signal_handler(int sig){ 
     LOCK(_lock_should_stop); 
     _should_stop = true; 
     UNLOCK(_lock_should_stop); 
    } 

    static bool _should_stop; 
    static bool _is_signal_registered; 
    static pthread_mutex_t _lock_should_stop, _lock_is_signal_registered; 
}; 

LoopInterface.cpp файл

#include "LoopInterface.h" 
bool LoopInterface::_should_stop = false; 
bool LoopInterface::_is_signal_registered = false; 
pthread_mutex_t LoopInterface::_lock_should_stop; 
pthread_mutex_t LoopInterface::_lock_is_signal_registered; 

И это, как он используется.

/************Threads*************/ 
#include "LoopInterface.h" 
class A : public LoopInterface{ 

}; 

void threadX(){ 
    A a; 
    while(!a.should_stop()){ 
     //do something... 
    } 
} 

Можете ли вы сказать, что этот интерфейс будет работать поточно-безопасно? или нет?

Если нет, в чем проблема?


Дополнительная проблема

Существует еще одна проблема, на мой синхронном коде.

тупики происходят довольно часто из-за вызов pthread_mutex_lock в signal_handler в то время как should_stop методе фиксации же mutex.

И я нашел article, заявив, что связанные с потоком функции не должны вызываться в обработчике сигнала.

Я думаю, что я должен найти другой способ синхронизации моих переменных-членов.

ответ

1

Очевидно, что этот код не является потокобезопасным: переменная _should_stop задается сигналом в некотором неконтролируемом потоке и считывается в LoopInterface, управляя собственным потоком. Синхронизация вообще отсутствует. Этот подход может быть только потокобезопасным, если имеется ровно один поток.

Вы можете сделать код потокобезопасной (по отношению к этой конкретной переменной) с использованием

static std::atomic<bool> _should_stop; 

Поскольку вы не заинтересованы в каких-либо других значений в данный момент, вы можете прочитать переменную с std::memory_order_relaxed флагами ,

Если конструктор из LoopInterface вызывается из нескольких потоков, вам также необходимо синхронизировать доступ к _is_signal_registered, конечно.

+0

спасибо. Но класс 'atom' кажется живущим в C++ 11, который мне недоступен. Я попробую синхронизировать две переменные с 'mutex'. –

+0

Уважаемый @Dietmar. Я добавил синхронизацию в код. Но я понятия не имею, как синхронизировать инициализацию двух объектов mutex здесь. –

+0

@JeaJunLEE: поскольку вы используете pthreads, вы можете просто использовать 'pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;', чтобы получить мьютекс, статически инициализированный. –

Смежные вопросы