2013-12-14 5 views
0

У меня есть проблема с мьютексами ...Мьютексов внутри, если условие

Это общая структура моего кода:

#include <mutex> 
std::mutex m; 

While(1){ 
    m.lock(); 
    if(global_variable1==1){ 
     //CODE GOES HERE 
     if (err==error::eof){ 
      cout<<"error!"<<endl; 
      //should I put a m.unlock() here?? 
      continue; 
     } 
     int something=1; 
     global_variable2=something; 
    } 
    m.unlock(); 
    usleep(100000); 

} 

В принципе, я хочу, чтобы изменить глобальные переменную безопасно, так что я думаю необходимо использовать мьютексы. Я должен только разблокировать мьютекс после этой функции «if (global_variable1 == 1)», но если есть ошибка, мьютекс не будет разблокирован. Могу ли я разблокировать его перед «продолжением»? Или это все испортит что-нибудь еще? Может ли иметь две разблокировки для одного и того же mutex.lock() иметь нежелательное поведение?

+0

вы должны гарантирую 'разблокировку();' вызов, но если вы поставите его перед 'продолжить,' вы можете быть уверены, что 'разблокировки(); 'будет называться в конце концов? –

+0

есть. Замок вызывается перед первым 'if'. Есть только два выхода: 'if (error)' и конец первого 'if'. есть разблокировка после первого if. Вопрос в том, должен ли я иметь тот, который прокомментирован? – Carollour

+0

Кажется, вы должны. В противном случае будет и разблокирован мьютекс, когда возникла ошибка после того, как 'continue' обходит нижнюю' unlock() ' –

ответ

1

Вот почему C++ имеет отдельный замок и мьютекс классы: замок представляет собой удобный класс RAII, который будет убедиться, что ваш мьютекс получает разблокирован, даже если исключения выбрасываются или какой-то другой идиот программист добавляет новый return/break/continue в программа. Вот как эта программа работает с std::unique_lock:

#include <mutex> 
std::mutex m; 

While(1){ 
    std::unique_lock<std::mutex> lock(m); 
    if(global_variable1==1){ 
     //CODE GOES HERE 
     if (err==error::eof){ 
      cout<<"error!"<<endl; 
      continue; 
     } 
     int something=1; 
     global_variable2=something; 
    } 
    lock.unlock(); 

    usleep(100000); 
} 
+0

Спасибо за ваш ответ! Я смог решить это уже – Carollour

1

ли не блокировки/разблокировки мьютексы вручную! Вместо этого используйте охрану, например, std::lock_guard<std::mutex>: охранник получит замок при строительстве, освободив его при уничтожении. Для того, чтобы ограничить время, на протяжении которого замок, просто использовать блок:

while (true) { 
    { 
     std::lock_guard<std::mutex> cerberos(m); 
     // ... 
    } 
    sleep(n); 
} 
+0

Я не уверен, что понял ... У меня несколько потоков, и поэтому я хотел использовать мьютексы, чтобы они не могли одновременно обращаться к глобальным переменным. Если я использую 'lock_guard', как узнать, когда произойдет его уничтожение, если я использую его в бесконечном цикле? – Carollour

+1

@Carollour: объекты уничтожаются, когда область действия, в которой они живут, выходит, независимо от того, как она выходит. помещая блок вокруг раздела кода, который необходимо синхронизировать с ним, и использует защитный элемент, аккуратно приобретает/освобождает блокировку в соответствующие моменты времени. –

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