허브 셔터는 약 C++ (11)과 동시성C++ 11에서 클래스의 모든 멤버 함수 호출을 래핑하는 방법은 무엇입니까?
이여기서 핵심 아이디어는 모든 함수 호출이 잠금 해제 잠금 장식한다 비 잠금 클래스 X
을하는 것입니다 (this video 참조) 이야기에서이 질문을 함수 후.
그러나 Herb Sutter는 표류하고 functor 기반 접근 방식을 제공합니다. C++ 11로 각 함수 호출을 잠금 및 클래스 잠금 해제와 함께 일반적인 방법 (모든 함수 호출을 수동으로 래핑하지 않음)으로 래핑하는 것이 가능한지 궁금합니다.
class X {
public:
X() = default;
void somefunc(arg1 x1, arg2 x2, ...);
void somefunc2(arg1 x1, arg2 x2, ...);
/* and more */
};
// herb admits one way to make all functions *available*
// in another class is by derivation
class XX : public X {
public:
XX() = default;
// all functions available in NON overloaded form...
};
또한 장식 패턴
class XXX {
public:
XXX(X &x) : m_x(x) {}
// explicitly call each wrapped function ... done for each class separately.
void somefunc(arg1 x1, arg2 x2, ...);
void somefunc2(arg1 x1, arg2 x2, ...);
private:
class X& m_x;
};
이 있지만 거기에이 가능한 같은 것입니다 :
template<>
class wrap_everything;
wrap_everything<X> x;
x.somefunc(x1,x2,...); // this is then locked.
완성도를 위해서이 허브 셔터의 펑 기반의 접근 방식은 다음과 같습니다
template <class T> class locker {
private:
mutable T m_t;
mutable std::mutex m_m;
public:
locker(T t = T{}) : m_t(t) {}
template <typename F>
auto operator()(F f) const -> decltype(f(m_t)) {
std::lock_guard<mutex> _{m_m};
return f(t);
}
};
// usage
locker<std::string> s;
s([](string &s) {
s += "foobar";
s += "barfoo";
});
일부 컴파일러 (예 : gcc)에서는 컴파일러가 코드를 수정하지 않고도이 작업을 수행 할 수 있습니다. 일반적으로 프로파일 링에 사용되지만 각 함수 호출 전후에 지정된 함수를 호출하도록 할 수 있습니다. 자물쇠를 원하는 위치와 실제로하지 않은 위치를 구분하는 코드는 여전히 중요하지 않습니다. –
@JerryCoffin 코드에서보다 다른 곳에서 잠금을 찾아야하는 것은 모든 관리자가 치명적입니다. – Alex
@Alex 좋은 질문입니다. 나는 Sutter가 2012 년 C++에서 그리고 Beyond 2012에서 그 때를 기억해 냈던 것을 기억하고 있습니다. 어쩌면 그는 C++ 14 기능 세트에 대한 힌트를 포기했을 수도 있습니다. –