2016-11-10 14 views
0

Во-первых, я хотел бы отметить, что я искал это, но не могу найти ответ, который я ищу/запутался с чрезмерно подробные ответы.Qt/C++: рекурсивные мьютексы, «зоны синхронизации» и блокирующие сигналы

У меня есть программа, которая использует два потока. А логические значения должны быть установлены и читать в тему А, но только для чтения в Thread В.

Тема A:

Module::Module(){ 
} 

void Module::foo(){ 
    mutex.lock(); 
    bool request = true; 
    mutex.unlock(); 
} 

void Module::bar(){ 
    mutex.lock(); 
    if (request){ 
     mutex.unlock(); 
     // do stuff 
    }else{ 
     mutex.unlock(); 
    } 
} 

Тема B:

Provider::Provider(){ 
    module = new Module; // pointer to class request 'lives in' 
} 

void Provider::foo(){ 
    mutex.lock(); 
    if (module->request){ 
     mutex.unlock(); 
     // do stuff 
     } 
    }else{ 
     mutex.unlock(); 
    } 
} 

Мой вопрос может показаться довольно тривиально, но это меня беспокоит. Thread A не может читать и писать одновременно, поэтому я бы утвердил, что рекурсивный мьютекс не требуется для A. Однако существует небольшая возможность foo(), и bar() может вызываться одновременно из Thread B (Сигналы и слоты) , Означает ли это, что мне нужен рекурсивный мьютекс?

Также; есть ли причина не использовать Qt :: BlockingQueudConnection? Коллега утверждал, что это опасно, поскольку он посылает вызовы потоков спать до тех пор, пока сигнал не выполнит слот, но разве это не похоже на мьютекс?

Кроме того; видел сообщение о структурировании мьютекса (pthread mutex locking variables used in statements). Здесь он упоминает создание локальных копий по значениям. Если бы я использовал что-то подобное для Thread A, например.

mutex.lock(); 
requestCopy = request; 
mutex.lock(); 
... 
if(requestCopy){ 
// do stuff 
} 

Будет ли это также блокировать доступ к запросу по запросу? Копия становится привычной? Я хотел использовать этот стиль в своем коде для простоты, но это не сработает, если вы прочтете И напишите в потоке?

Любая помощь будет замечательной.

+0

Я не вижу бар() где-либо, вызванный из потока B. –

+1

Возможно, вне темы, но ... с точки зрения безопасности исключений вы должны предпочесть ['RAII'] (http://en.cppreference.com/w/cpp/язык/raii) стиль блокировки с использованием, например, ['lock_guard'] (http://en.cppreference.com/w/cpp/thread/lock_guard), а не явные пары' lock'/'unlock'. –

+0

Спасибо @ G.M. Немного новичок в этом, так что заглянем в него. Olaf Dietsche - извините за простоту, которую я не показывал, но bar() время от времени будет вызываться asysnc из Thread B. Я разработал его так, чтобы Thread A & B не вызывал foo() одновременно - однако Я не могу этого гарантировать. – SamMetix

ответ

0

Из того, что вы показали, это выглядит как (переписан)

Некоторые модуль (Thread A):

class Module { 
private: 
    bool request = false; 
    QMutex m; 
public:  
    void set_request(bool b) { 
     QMutexLocker lock(&m); 
     request = b; 
    } 

    bool get_request() { 
     QMutexLocker lock(&m); 
     return request; 
    } 

    void bar() { 
     if (get_request()) { 
      // do stuff 
     } 
    } 
}; 

Тема B:

class Provider { 
public: 
    Provider() { 
     module = new Module(); 
    } 

    void foo() { 
     if (module->get_request()){ 
      // do stuff 
     } 
    } 
private: 
    Module *module; 
}; 

Если это действительно так (и все в порядке), нет необходимости в рекурсивном мьютексе.

+0

Привет, спасибо за быстрый ответ. Я использую QMutex (хотя, возможно, я должен использовать std :: mutex). Очень жаль путаницы: в моих потоках работают два класса (в циклах событий). Так что в потоке A работает модуль, а в потоке B работает класс, получающий указатель на Module (module-> request). Кроме того, foo() является эффективным средством настройки, но bar() не является получателем - он проверяет переменную запроса. Модуль имеет два метода - foo() & bar(). Поставщик (Thread B) имеет foo(). – SamMetix

+0

Глядя на QMutex, используя ['QMutexLocker'] (http://doc.qt.io/qt-5/qmutexlocker.html), похоже, делает то же самое. –

+0

Хорошо, спасибо за быстрые ответы - очень ценю это. – SamMetix

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

  • Нет связанных вопросов^_^