Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Thread safety 
:(
    Опции темы
Lazin
Дата 5.2.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Меня уже давно ломает то, как приходится работать с общими данными в многопоточных программах на С++
Использование lock-ов ломает модульность, классический пример: у нас есть класс - хэш таблица, которую можно безопасно использовать в многопоточных программах. Но если у нас есть 2 такие таблицы и нам нужно взять элемент из одной и вставить в другую, то другой поток может обратиться к таблицам между этими операциями и не найти этот элемент ни в одной из таблиц. В некоторых случаях это будет проблемой.
У меня появилась идея как это побороть, но видимо не очень удачная.
Принцип работы такой. Доступ к объекту производится не на прямую, а через proxy объект, который создается на стеке и во время создания блокирует объект которым владеет. Если создать несколько таких accessor-ов, то можно работать с ними атомарно(если конечно методы lock и unlock объектов правильно реализованы). Если все методы будут вызываться не на прямую а через accessor-ы то с одним объектом можно работать безопасно из разных потоков не опасаясь race-ов.
Вот код:
Код

namespace concurrency
{
    template<
        class T, 
        class Owner, 
        T (Owner::*getter)(),
        void (Owner::*setter)(const T&),
        void (Owner::*lock)(),
        void (Owner::*unlock)()
    >
    class generic_accessor
    {
        Owner& owner_;
    public:
        generic_accessor(Owner& o) : owner_(o)
        {
            (owner_.*lock)();
        }
        ~generic_accessor()
        {
            (owner_.*unlock)();
        }
        generic_accessor& operator = (const T& s)
        {
            (owner_.*setter)(s);
            return *this;
        }
        operator T () const 
        {
            return (owner_.*getter)();
        }
        friend std::ostream& operator << (std::ostream& os, generic_accessor& a)
        {
            os << (T)a << std::endl;
            return os;
        }
    };
};

class Foo
{
    typedef Foo type;
    std::string value_;
public:
    Foo(const char* val) : value_(val) {}
private:
    std::string get()
    {
        return value_;
    }
    void set(const std::string& v)
    {
        value_.assign(v);
    }
    void lock()
    {
        std::cout << "lock Foo:" << value_ << std::endl;
    }
    void unlock()
    {
        std::cout << "unlock Foo:" << value_ << std::endl;
    }
public:
    typedef concurrency::generic_accessor<std::string, Foo, &Foo::get, &Foo::set, &Foo::lock, &Foo::unlock> accessor;
};



int _tmain(int argc, _TCHAR* argv[])
{

    Foo foo("foo");
    Foo bar("bar");
    {
        Foo::accessor a(foo);
        Foo::accessor b(bar);
        std::cout << a << std::endl;
        std::cout << b << std::endl;
    }
    //exchange names
    {
        Foo::accessor a(foo);
        Foo::accessor b(bar);
        std::string tmp = a;
        a = b;
        b = tmp;
    }
    {
        Foo::accessor a(foo);
        Foo::accessor b(bar);
        std::cout << a << std::endl;
        std::cout << b << std::endl;
    }
    system("pause");
    return 0;
}

при таком подходе, производительность будет такой-же как и при традиционном подходе (как если-бы я просто добавил методы accessor-ы в класс Foo и вызывал-бы там методы lock - unlock).
Но этот подход не избавляет от возможности возникновения deadlock-ов, так-как 2 разных потока могут попытаться залочить пару объектов но в разном порядке, то-есть код использующий 2 и более accessor-a все равно нуждается в синхронизации. 
Как это можно побороть? Есть-ли какие либо техники организации порядка блокировок в таком случае?
PM MAIL Skype GTalk   Вверх
Vaulter
Дата 5.2.2009, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 2
Всего: 22



Семафоры?


--------------------
PM MAIL WWW ICQ   Вверх
Lazin
Дата 6.2.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(Vaulter @  5.2.2009,  17:48 Найти цитируемый пост)
Семафоры? 

нет
я думал о каком-нибудь механизме, вроде composed transactional memory, но только на уровне архитектуры, видимо я хочу странного =)
PM MAIL Skype GTalk   Вверх
andrew_121
Дата 6.2.2009, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Если не семафоры, то что? Или я чего-то не понимаю...?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lazin
Дата 6.2.2009, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



или
PM MAIL Skype GTalk   Вверх
andrew_121
Дата 6.2.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(Lazin @ 6.2.2009,  12:11)
или

Спасибо за информативность...


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0452 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.