C ++ адаптирует библиотеку для многопоточности - PullRequest
4 голосов
/ 14 января 2012

Я работаю с libconfig ++ и потоками для создания небольшого серверного приложения.Дело в том, что libconfig ++ не является потокобезопасным , поэтому моя идея состоит в том, чтобы создать еще один класс, который действует как обертка с 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 поддерживает множество типов для своих переменных.И вот тогда наш главный герой (я) оказывается в поиске любого гуру C ++ с добрым сердцем, готовым показать ему любой способ заставить это работать.

По существу, функции get и set могут понадобитьсяпеременная std::string или char* path, содержащая путь к переменной файла конфигурации (я бы не возражал против этого) и тип возвращаемого значения (или второй аргумент в случае set) должны отличаться...

Как всегда, любая помощь будет оценена.

Джулиан

Ответы [ 2 ]

1 голос
/ 14 января 2012

Вы могли бы также использовать этот подход. Я думаю, что его сложнее не использовать и, следовательно, лучше. Экземпляр 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;
}
1 голос
/ 14 января 2012

Вы можете написать класс декоратора, который перенаправляет все вызовы функций в частный экземпляр 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...