Re[6]: Порядок создания объектов
От: MaximE Великобритания  
Дата: 05.11.04 07:56
Оценка: 7 (1)
vdimas wrote:

> ME>function static — хороший способ создания проблем в многопотоковом коде. Сегодня у тебя этот static инициализирует один поток, завтра — ?, и компилятор здесь тебе не поможет никакой диагностикой.

>
> Интерфейс важнее реализации, IMHO.

Согласен, что интерфейс очень важен. Не согласен что его важность можно сравнивать с важностью реализации — на мой взгляд эти вещи несравнимы.

> functional static — хорошее ср-во инкапсуляции подробностей обеспечения гарантированного порядка создания объектов, в данном случае — по мере их использования друг-другом.


[]

У меня противоположное мнение: функции с состоянием (со static) в С и С++, на мой взглад, плохая вещь из-за проблем с multithreaded code и из-за неявной зависимости инициализации/изменения этого состояния от последовательности вызовов (пример — strtok).

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re: Порядок создания объектов
От: Анатолий Широков СССР  
Дата: 02.11.04 08:30
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Есть такой текст:



А>
А>class MyClass {
А>public:
А>  MyClass();
А>  static TMutex& get_mutex()
    {
        static TMutex mutex;
        return mutex; 
    }
А>};

А>


А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?
Re[2]: Порядок создания объектов
От: MaximE Великобритания  
Дата: 02.11.04 08:51
Оценка: :)
On Tue, 02 Nov 2004 08:30:15 GMT, Анатолий Широков <12237@news.rsdn.ru> wrote:

> А>
> А>class MyClass {
> А>public:
> А>  MyClass();
> А>  static TMutex& get_mutex()
>     {
>         static TMutex mutex;
>         return mutex;
>     }
> А>};
>
> А>


У меня есть подозрение, что человек создает мьютекс именно в малтифредовой проге А такой код совсем не thread safe.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re[3]: Порядок создания объектов
От: Bell Россия  
Дата: 02.11.04 09:02
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Bell, Вы писали:


B>>Имеются ввиду глобальные объекты класса MyClass?


А>Дело не в этом. Заранее я не знаю, как будут объявляться (или определяться?) объекты. Главное — чтобы во время вызова конструктора MyClass объект класса TMutex уже существовал. Способ Анатолия Широкова подходит.


Все не так просто.
Предположим, что имеется 2 потока, и эти 2 потока одновременно создают по экземрляру MyClass, соответственно в их конструкторах имеем одновременный вызов get_mutex, а это может окончится не очень хорошо...
Любите книгу — источник знаний (с) М.Горький
Re[2]: Порядок создания объектов
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 03.11.04 13:41
Оценка: +1
Здравствуйте, vdimas, Вы писали:
V>функциональный синглтон, создаст объект при первом обращении:

V>
V>TMutex& global_mutex() {
V>    static TMutex t;
V>    return t;
V>}

V>...

V>// и в программе везде юзаешь:

V>global_mutex().TryLock();
V>


V>получишь глобальный в пределах бинарника статический экземпляр мютекса,

V>вся эта кухня будет корректно работать даже на границах между бинарниками (из других DLL).

Насколько я помню, вызов конструктора статической переменной может отложиться до первого вызова любой функции,
определенной в том же TU. Это может произойти после вызова main, когда у тебя уже >1 потока.
Порядок создания объектов
От: Аноним  
Дата: 02.11.04 08:26
Оценка:
Есть такой текст:


class MyClass {
public:
  MyClass();
  static TMutex mutex;
};
...

TMutex MyClass::mutex;


Как мне добиться, чтобы во время создания объекта класса MyClass
(вообще говоря, в другом модуле) объект mutex уже был создан?
Re: Порядок создания объектов
От: KneLL Украина  
Дата: 02.11.04 08:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть такой текст:


А>
А>class MyClass {
А>  static TMutex mutex;
А>};
А>...

А>TMutex MyClass::mutex;
А>


Насколько я помню стандарт не определяет порядок инициализации статических членов в разных модулях. Зависит от компилятора.
Re: Порядок создания объектов
От: e-smirnov  
Дата: 02.11.04 08:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?

Создай заранее служебный объект класса MyClass, иначе, по-моему, не получится...
Или сделай мьютекс глобальным...
Re: Порядок создания объектов
От: Bell Россия  
Дата: 02.11.04 08:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть такой текст:



А>
А>class MyClass {
А>public:
А>  MyClass();
А>  static TMutex mutex;
А>};
А>...

А>TMutex MyClass::mutex;
А>


А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?
Имеются ввиду глобальные объекты класса MyClass?
Любите книгу — источник знаний (с) М.Горький
Re[2]: Порядок создания объектов
От: Аноним  
Дата: 02.11.04 08:46
Оценка:
Здравствуйте, Анатолий Широков.

Спасибо. То, что надо!
Re: Порядок создания объектов
От: Glоbus Украина  
Дата: 02.11.04 08:52
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?

могу ошибаться,но ко времени создания объекта MyClass статический объект уже будет существовать и без дополнительбных телодвижений с твоей стороны.
Удачи тебе, браток!
Re[2]: Порядок создания объектов
От: Аноним  
Дата: 02.11.04 08:52
Оценка:
Здравствуйте, Bell, Вы писали:

B>Имеются ввиду глобальные объекты класса MyClass?


Дело не в этом. Заранее я не знаю, как будут объявляться (или определяться?) объекты. Главное — чтобы во время вызова конструктора MyClass объект класса TMutex уже существовал. Способ Анатолия Широкова подходит.
Re[2]: Порядок создания объектов
От: Аноним  
Дата: 02.11.04 08:55
Оценка:
Здравствуйте, Glоbus, Вы писали:

G>могу ошибаться,но ко времени создания объекта MyClass статический объект уже будет существовать и без дополнительбных телодвижений с твоей стороны.


Действительно ошибаешься. Программа уже гуляет где-то, а мьютекса все нет
Re: Порядок создания объектов
От: vdimas Россия  
Дата: 02.11.04 08:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть такой текст:



А>
А>class MyClass {
А>public:
А>  MyClass();
А>  static TMutex mutex;
А>};
А>...

А>TMutex MyClass::mutex;
А>


А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?

функциональный синглтон, создаст объект при первом обращении:

TMutex& global_mutex() {
    static TMutex t;
    return t;
}

...

// и в программе везде юзаешь:

global_mutex().TryLock();


получишь глобальный в пределах бинарника статический экземпляр мютекса,
вся эта кухня будет корректно работать даже на границах между бинарниками (из других DLL).
Re[4]: Порядок создания объектов
От: vdimas Россия  
Дата: 02.11.04 10:25
Оценка:
Здравствуйте, Bell, Вы писали:

B>Все не так просто.

B>Предположим, что имеется 2 потока, и эти 2 потока одновременно создают по экземрляру MyClass, соответственно в их конструкторах имеем одновременный вызов get_mutex, а это может окончится не очень хорошо...

Да, ты бы был прав, если бы не одно "но". У человека там конфликты возникают в момент инициализации модулей, т.е. в телах конструкторов статических объектов. Прежде, чем у тебя появиться возможность создать второй поток, этот мютекс (именно рассматриваемй случай), будет уже создан.
Re[5]: Порядок создания объектов
От: Bell Россия  
Дата: 02.11.04 10:34
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Bell, Вы писали:


B>>Все не так просто.

B>>Предположим, что имеется 2 потока, и эти 2 потока одновременно создают по экземрляру MyClass, соответственно в их конструкторах имеем одновременный вызов get_mutex, а это может окончится не очень хорошо...

V>Да, ты бы был прав, если бы не одно "но". У человека там конфликты возникают в момент инициализации модулей, т.е. в телах конструкторов статических объектов. Прежде, чем у тебя появиться возможность создать второй поток, этот мютекс (именно рассматриваемй случай), будет уже создан.


Вот поэтому в своем первом вопросе я и спросил — о глобальных объектах речь, или нет. Из текста вопроса совсем не очевидно, что речь о них.
Любите книгу — источник знаний (с) М.Горький
Re: Порядок создания объектов
От: Аноним  
Дата: 02.11.04 12:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть такой текст:


А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?

У Александреску эта тема довольно подробно рассмотрена (глава про синглтоны).
Re[2]: Порядок создания объектов
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 03.11.04 13:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Есть такой текст:


А>>Как мне добиться, чтобы во время создания объекта класса MyClass

А>>(вообще говоря, в другом модуле) объект mutex уже был создан?

А>У Александреску эта тема довольно подробно рассмотрена (глава про синглтоны).


И это надо обязательно прочитать:
Scott Meyers & Alexandrescu
C++ and the Perils of Double-Checked Locking
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
Re[3]: Порядок создания объектов
От: vdimas Россия  
Дата: 03.11.04 17:30
Оценка:
Здравствуйте, alnsn, Вы писали:

A>Насколько я помню, вызов конструктора статической переменной может отложиться до первого вызова любой функции,

A>определенной в том же TU. Это может произойти после вызова main, когда у тебя уже >1 потока.

а речь идет о статической переменной, или глобальной?
Re[5]: Порядок создания объектов
От: AlexanderDz  
Дата: 04.11.04 08:10
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Bell, Вы писали:


B>>Все не так просто.

B>>Предположим, что имеется 2 потока, и эти 2 потока одновременно создают по экземрляру MyClass, соответственно в их конструкторах имеем одновременный вызов get_mutex, а это может окончится не очень хорошо...

V>Да, ты бы был прав, если бы не одно "но". У человека там конфликты возникают в момент инициализации модулей, т.е. в телах конструкторов статических объектов. Прежде, чем у тебя появиться возможность создать второй поток, этот мютекс (именно рассматриваемй случай), будет уже создан.


А что если статические объекты в конструкторе создают потоки?

Александр
Re[4]: Порядок создания объектов
От: MaximE Великобритания  
Дата: 04.11.04 08:24
Оценка:
vdimas wrote:

> Здравствуйте, alnsn, Вы писали:

>
> A>Насколько я помню, вызов конструктора статической переменной может отложиться до первого вызова любой функции,
> A>определенной в том же TU. Это может произойти после вызова main, когда у тебя уже >1 потока.
>
> а речь идет о статической переменной, или глобальной?

Здесь это не так важно.

function static — хороший способ создания проблем в многопотоковом коде. Сегодня у тебя этот static инициализирует один поток, завтра — ?, и компилятор здесь тебе не поможет никакой диагностикой.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re[6]: Порядок создания объектов
От: vdimas Россия  
Дата: 05.11.04 06:56
Оценка:
Здравствуйте, AlexanderDz, Вы писали:

AD>А что если статические объекты в конструкторе создают потоки?


А что если за это руки оторвать?

Дело не только в потоках, разумеется. Считаю неправильным нагружать конструкторы статических объектов дополнительной функциональностью кроме основной — конструирование объекта. В лучшем случае — саморегистрация где-нить.
Почему считаю неправильным? Именно из-за отсутствия гарантированной последовательности загрузки бинарных модулей и отсутствия гарантированного поряжка инициализации объектных модулей в них.

------
Еще один поток это еще одна ветвь алгоритма, который в данном случае будет пытаться работать с еще "незапущенной" программой.
Re[5]: Порядок создания объектов
От: vdimas Россия  
Дата: 05.11.04 07:34
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>function static — хороший способ создания проблем в многопотоковом коде. Сегодня у тебя этот static инициализирует один поток, завтра — ?, и компилятор здесь тебе не поможет никакой диагностикой.


Интерфейс важнее реализации, IMHO.
functional static — хорошее ср-во инкапсуляции подробностей обеспечения гарантированного порядка создания объектов, в данном случае — по мере их использования друг-другом.

никто не мешает потом сделать нечто вроде:
template<typename T, T* (*unique_func)(bool) >
struct fstatic_body 
{
    static T* obj;
    static mutex mt;

    // вызываем этот метод в теле многопоточной программы
    static T* get_mt() {
        if(!obj) {
            guard lock(mt);
            if(!obj)
                obj = new T();
        }

        return obj;
    }

    // вызываем этот метод в теле конструкторов глобальных объектов
    static T* get() {
        if(!obj)
            obj = new T();

        return obj;
    }

    ~fstatic_body() { if(obj) delete obj; } // грохаем статический объект в деструкторе экземпляра :)
};

template<typename T, T* (*unique_func)(bool)> 
T* fstatic_body<T, unique_func>::obj = NULL;

template<typename T, T* (*unique_func)(bool)> 
mutex fstatic_body<T, unique_func>::mt;

struct SomeType {};

SomeType* get_some_obj(bool from_ctor = false) {
    static fstatic_body<SomeType, get_some_obj> st;
    if(from_ctor)
        return st.get();     // :)
    else
        return st.get_mt();
}

// можно макросом подсобить
#define DEF_SGTON(type, name) \
// тут переписать ф-ию get_some_obj с подстановкой type и name


Автору топика — бери как решение.
Re[7]: Порядок создания объектов
От: vdimas Россия  
Дата: 09.11.04 01:33
Оценка:
Здравствуйте, MaximE, Вы писали:

>> Интерфейс важнее реализации, IMHO.


ME>Согласен, что интерфейс очень важен. Не согласен что его важность можно сравнивать с важностью реализации — на мой взгляд эти вещи несравнимы.


Важно — не важно, это все абстрактные понятия, разумеется. А вот трудозатраты — это уже очень даже осязаемая величина. В общем случае трудозатраты на переделку интерфейса на порядок выше, чем некоего куска имплементации.

ME>У меня противоположное мнение: функции с состоянием (со static) в С и С++, на мой взглад, плохая вещь из-за проблем с multithreaded code и из-за неявной зависимости инициализации/изменения этого состояния от последовательности вызовов (пример — strtok).


похоже, ты таже не взглянул на приведенный код... жаль, зря старался.

там код, который выглядит как fuctional static, но таковым не является
Re: Порядок создания объектов
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 09.11.04 02:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как мне добиться, чтобы во время создания объекта класса MyClass

А>(вообще говоря, в другом модуле) объект mutex уже был создан?

Может воспользоваться статическим mutex? Работает под виндой:
/// Static mutex.
template<class T>
class static_mutex
{
public:
    /// Scoped lock.
    class scoped_lock: boost::noncopyable
    {
    public:
        /// Constructor. Lock.
        scoped_lock() { while(InterlockedExchange(&X, 1)) Sleep(1); }
        /// Destructor. Unlock.
        ~scoped_lock() { InterlockedExchange(&X, 0); }    
    };
private:
    static volatile LONG X;
};

template<class T>
volatile LONG static_mutex<T>::X = 0;


Твой код будет выглядеть так:
class MyClass {
public:
  MyClass();
};


А использование так:
    {
        static_mutex<MyClass>::scoped_lock Lock;
        ...
    }


P.S. Удобно для синглтонов.
getboost.codeplex.com
citylizard.codeplex.com
Re[8]: Порядок создания объектов
От: MaximE Великобритания  
Дата: 09.11.04 05:14
Оценка:
Здравствуйте, vdimas, Вы писали:

ME>>У меня противоположное мнение: функции с состоянием (со static) в С и С++, на мой взглад, плохая вещь из-за проблем с multithreaded code и из-за неявной зависимости инициализации/изменения этого состояния от последовательности вызовов (пример — strtok).


V>похоже, ты таже не взглянул на приведенный код... жаль, зря старался.


V>там код, который выглядит как fuctional static, но таковым не является


Не волнуйся, видел я твой код. О его применимости сказать ничего не могу — подобные синглтоны я не использую.
Re[9]: Порядок создания объектов
От: vdimas Россия  
Дата: 09.11.04 11:14
Оценка:
Здравствуйте, MaximE, Вы писали:

V>>там код, который выглядит как fuctional static, но таковым не является


ME>Не волнуйся, видел я твой код. О его применимости сказать ничего не могу — подобные синглтоны я не использую.


Да речь не о синглтонах, разумеется. Синглтон — это лишь реализация. Дело в том, что подобные ф-ии, инкапсулирующие способ создания статических объектов сами по себе выглядят как API. На этапе начальной разработки (или разработки под 1 тред) можно накидывать это тело из 2-х строчек, т.е. юзать обычный functional static. Если позже требования ужесточаются, то одно из решений я привел.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.