2017-12-07 18 views
1


C++에서 변경할 수있는 것은 무엇입니까?

이 코드는 순차 프로그래밍 및 잠금 프로그래밍에서 제공되었습니다. 차이점을 분석해야하지만 일부 코드가 무엇을하는지 확신 할 수 없습니다. 이 코드는 아래에 있으며, 내가 이해하지 못하는 부분은 총알에서도 언급되어 있습니다. 키워드의

  • 효과 : 변경 가능한이
    • 또 다른 StackOverflow의 대답은 가변가 CONST가
      수정하지만 난 그이 프로젝트
    • 이란 무엇입니까 무슨 상관이 표시되지 않습니다 할 수 있다고 이 프로그램에서 "mutable"제거 효과? 자물쇠를 해제합니까? 이 이해 나의 부족을 더욱 확대하여 not_full 및 not_empty
      • 에 대한 변경 가능한
    • , 왜 가변 not_full 및 not_empty 필요하지 않습니다?

읽기 주셔서 감사합니다, 어떤 도움을 주시면 감사하겠습니다!

<pre><code> 
    #ifndef LOCKEDBUFFER_H 
    #define LOCKEDBUFFER_H 

    #include <memory> 
    #include <mutex> 
    #include <condition_variable> 
    #include <atomic> 

    #include "optional.h" 

    template <typename T> 
    class locked_buffer { 
    public: 
     // Creates buffer of size n 
     locked_buffer(int n) : 
     size_{n}, 
     buf_{new optional<T>[size_]} 
     { 
     } 

     // Remove copy constructor 
     locked_buffer(const locked_buffer &) = delete; 

     // Destructor (default generated) 
     ~locked_buffer() = default; 

     // Gets buffer size 
     int size() const noexcept { 
     return size_; 
     } 

     // Checks if buffer is empty 
     bool empty() const noexcept { 
     std::lock_guard<std::mutex> l{mut_}; 
     return is_empty(); 
     } 

     // Checks if buffer is full 
     bool full() const noexcept { 
     std::lock_guard<std::mutex> l{mut_}; 
     return is_full(); 
     } 

     // Put an optional value in the queue 
     void put(const optional<T> & x); 

     // Get a value from the queue 
     optional<T> get(); 

    private: 
     // Next circular position to position p 
     int next_position(int p) const noexcept { 
     return p + ((p+1>=size_)?(1-size_):1); 
     } 

     // Check if buffer is empty without locking 
     bool is_empty() const noexcept { 
     return (next_read_ == next_write_); 
     } 

     // Check if buffer is full without locking 
     bool is_full() const noexcept { 
     const int next = next_position(next_write_); 
     return next == next_read_; 
     } 

    private: 
     const int size_; 
     const std::unique_ptr<optional<T>[]> buf_; 
     int next_read_ = 0; 
     int next_write_ = 0; 

     mutable std::mutex mut_; 
     std::condition_variable not_full_; 
     std::condition_variable not_empty_; 
    }; 


    template <typename T> 
    void locked_buffer<T>::put(const optional<T> & x) 
    { 
     using namespace std; 
     unique_lock<mutex> l{mut_}; 
     not_full_.wait(l, [this] { return !is_full(); }); 
     buf_[next_write_] = x; 
     next_write_ = next_position(next_write_); 
     not_empty_.notify_one(); 
    } 

    template <typename T> 
    optional<T> locked_buffer<T>::get() 
    { 
     using namespace std; 
     unique_lock<mutex> l{mut_}; 
     not_empty_.wait(l, [this] { return !is_empty(); }); 
     auto res = buf_[next_read_]; 
     next_read_ = next_position(next_read_); 
     not_full_.notify_one(); 
     return res; 
    } 

    #endif 
+1

'const' 메소드에서도 뮤텍스를 잠글 수있게하는 것 같습니다. – user463035818

+1

'mutable'은 잠금과 아무 관계가 없습니다. 이 코드에서 제거하면 대부분 컴파일되지 않습니다. –

+0

http://en.cppreference.com/w/cpp/language/cv가 도움이 될 수 있습니다. –

답변

3

단계별로 살펴 보겠습니다.

또 다른 StackOverflow의 응답

은 변경할 수는 CONST가 수정하지만 난 그 이것은 어떻게 든 클래스에 적용 않습니다이 프로젝트

와 무슨 상관이 표시되지 않습니다 할 수 있다고 말한다. 이 방법이 있습니다.

bool empty() const noexcept { 
    std::lock_guard<std::mutex> l{mut_}; 
    return is_empty(); 
} 

lock guardlock_guard 같은 비 CONST 개체 참조가 뮤텍스를 변경할 것으로 기대. 하지만 메서드가 const이기 때문에 const가 아닌 방식으로 멤버에 액세스 할 수 없습니다. 여기서 mutable이 작동하는 곳입니다.

이 프로그램에서 "변경 가능"을 제거하면 어떤 영향이 있습니까? 잠금을 해제합니까?

에서 사용자가 변경할 수를 제거하면

당신의 mutex 당신이 empty()full() 방법에 컴파일 오류가 발생합니다. 그래서 기술적으로 자물쇠는 무능력하지 않지만 당신의 프로그램은 형편 없습니다.

왜 내 이해 부족, 왜 not_full 및 not_empty 필요없는 변경할 수 있습니까?

비 const 메소드에서 사용되기 때문에 간단합니다.
그래서 변경할 필요가 없습니다. const 메서드에서 그것들 중 하나를 사용하고 condition_variable에서 const가 아닌 메서드를 사용하고자한다면 변경 가능하게 만들어야합니다.