我正在使用libconfig ++和线程来制作一个小型服务器应用程序。关键是,libconfig++ is not thread safe,所以我的想法是创建另一个类,它充当了Mutex的包装器,如下所示:
class app_config {
public:
app_config();
/* Here be my problems. */
void set();
void get();
virtual ~app_config();
private:
Config cfg;
boost::mutex *cfg_mutex;
};
现在,在我意识到libconfig supports plenty of types的变量之前,这一切都很好。那就是当我们的主角(我)发现自己正在寻找任何一位C ++大师时,他心地善良地向他展示了如何使其发挥作用。
基本上,get
和set
函数需要std::string
或char*
path
变量,其中包含配置文件变量的路径(我不会不介意使用任何一种)和返回类型(或set
的情况下的第二个参数)应该有所不同......
与往常一样,任何帮助都将受到赞赏。
儒略
答案 0 :(得分:1)
您可以编写一个装饰器类,将所有函数调用转发给私有libconfig实例。这意味着您需要将要使用的所有函数添加到装饰器中。 另一种可能性是将对libconfig的调用转发给执行实际锁定的类。
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/bind.hpp>
class MultithreadingWrapper {
public:
template <class V, class T>
V ExecuteThreadSaveWithReturn(T func) {
boost::lock_guard<boost::mutex> l(m_Mutex);
return func();
}
template <class T>
void ExecuteThreadSave(T func) {
boost::lock_guard<boost::mutex> l(m_Mutex);
func();
}
private:
boost::mutex m_Mutex;
};
void f() {}
void f(int) { }
int f(int, int) { return 0; }
int main() {
MultithreadingWrapper wrapper;
wrapper.ExecuteThreadSave(boost::bind(f));
wrapper.ExecuteThreadSave(boost::bind(f, 1));
int i = wrapper.ExecuteThreadSaveWithReturn<int>(boost::bind(f, 1, 1));
return i;
}
答案 1 :(得分:1)
你也可以使用这种方法。我认为更难以错过,因此更优越。 Libconfig实例是包装器内部的私有成员,没有锁定就无法访问。
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/shared_ptr.hpp>
class Libconfig {
public:
int Get(const char*) { return 0; }
};
class LibConfLock;
class LibconfMultithreadingWrapper {
friend class LibConfLock;
public:
LibconfMultithreadingWrapper()
:m_Libconfig(new Libconfig())
,m_Mutex(new boost::mutex())
{}
private:
boost::shared_ptr<Libconfig> m_Libconfig;
boost::shared_ptr<boost::mutex> m_Mutex;
};
class LibConfLock {
public:
LibConfLock(const LibconfMultithreadingWrapper& wrapper)
:m_Libconfig(wrapper.m_Libconfig)
,m_Mutex(wrapper.m_Mutex)
,m_Lock(new LockType(*m_Mutex))
{}
Libconfig& GetLibconf() const { return *m_Libconfig; }
private:
typedef boost::lock_guard<boost::mutex> LockType;
boost::shared_ptr<Libconfig> m_Libconfig;
boost::shared_ptr<boost::mutex> m_Mutex;
boost::shared_ptr<LockType> m_Lock;
};
int main() {
LibconfMultithreadingWrapper wrapper;
int i = LibConfLock(wrapper).GetLibconf().Get("hallo");
return i;
}