2015-03-19 3 views
1

У меня есть код, который я пытаюсь защитить с помощью механизма блокировки форсирования. Проблема заключается в том, что RecomputeStuff может быть вызван не только из RemoveStuff, но также может быть вызван из другого потока. Мой вопрос в том, что с помощью этих механизмов блокировки буксировки, какой правильный способ исправить RecomputeStuff? То, как это сейчас, является взаимоблокировками.блокировка блокировки мьютексов

#include <boost/thread.hpp> 

boost::shared_mutex values_mutex; 

int globaldata; 

class A 
{ 
public: 
    void RecomputeStuff(); 
    void RemoveStuff(); 
private: 
    std::vector<std::string> data; 
}; 

//Note, RecomputeStuff just reads from std::vector<std::string> data, but it also writes to other global stuff that RemoveStuff also writes to. 
void A::RecomputeStuff() 
{ 
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex); 
    boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); 

    // this function reads std::vector<std::string> data 
    // but also modifies `globaldata` that RemoveStuff also modifies. 
} 

void A::RemoveStuff() 
{ 
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex); 
    boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); 

    //here, remove stuff from std::vector<std::string> data 
    //...then call RecomputeStuff 

    RecomputeStuff(); 

    // modify `globaldata` 
} 

ответ

1

Решение состоит в том, чтобы переместить не заблокированный код метода A::RecomputeStuff к отдельному одному и вызвать его из A::RemoveStuff и A::RecomputeStuff. Смотрите ниже код

boost::shared_mutex values_mutex; 

int globaldata; 

class A 
{ 
private: 
    void RecomputeStuffUnsafe(); 
public: 
    void RecomputeStuff(); 
    void RemoveStuff(); 
private: 
    std::vector<std::string> data; 
}; 

void A::RecomputeStuffUnsafe() 
{ 
    // this function reads std::vector<std::string> data 
    // but also modifies `globaldata` that RemoveStuff also modifies. 
} 


//Note, RecomputeStuff just reads from std::vector<std::string> data, but it also writes to other global stuff that RemoveStuff also writes to. 
void A::RecomputeStuff() 
{ 
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex); 
    boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); 

    RecomputeStuffUnsafe(); 
} 

void A::RemoveStuff() 
{ 
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex); 
    boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); 

    //here, remove stuff from std::vector<std::string> data 
    //...then call RecomputeStuff 

    RecomputeStuffUnsafe(); 

    // modify `globaldata` 
} 

Edit # 00:

Также upgrade_lock имеет constructor, который принимает try_to_lock_t тег. Похоже на то, о чем вы просите.

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