sequence points
От: Dmi_3 Россия  
Дата: 07.11.05 22:27
Оценка: 8 (1) :)))
Если кто хочет подробнее разобраться с этим то добавьте в свой проект

template<class A,class B>
B&
operator,(A const&,B&b)throw()
{
  return(b);
}


масса "приятного" гарантирована.
А казалось бы чего страшного
Re: sequence points
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 08.11.05 08:43
Оценка:
Здравствуйте, Dmi_3, Вы писали:

D_>Если кто хочет подробнее разобраться с этим то добавьте в свой проект


D_>
D_>template<class A,class B>
D_>B&
D_>operator,(A const&,B&b)throw()
D_>{
D_>  return(b);
D_>}
D_>


D_>масса "приятного" гарантирована.

D_>А казалось бы чего страшного

Злой ты...
Хотя я сам запятую у себя в коде почти не использую -- даже не уверен, что в коде за последние полгода найду более 3-х использований (именно бинарной операции "запятая") -- и то в цикле for для изменения нескольких переменных -- так что мне не страшно.

А почем это так бьет -- по стлю, что ли?
Re: sequence points
От: MaximE Великобритания  
Дата: 08.11.05 09:56
Оценка:
On Mon, 07 Nov 2005 22:27:48 -0000, Dmi_3 <24209@users.rsdn.ru> wrote:

> Если кто хочет подробнее разобраться с этим то добавьте в свой проект

>
>
> template<class A,class B>
> B&
> operator,(A const&,B&b)throw()
> {
>   return(b);
> }
>

>
> масса "приятного" гарантирована.
> А казалось бы чего страшного

Перегруженный operator,() не есть sequence point, встроенный же — sequence point.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: sequence points
От: Кодт Россия  
Дата: 08.11.05 10:13
Оценка: +1 :)
Здравствуйте, Dmi_3, Вы писали:

Из серии wish you happy debug?
Можно ещё перегрузить && и || — тоже обеспечена масса приключений.
Перекуём баги на фичи!
Re: sequence points
От: ruslan_abdikeev Россия http://aruslan.nm.ru
Дата: 08.11.05 17:51
Оценка:
Здравствуйте, Dmi_3, Вы писали:

D_>template<class A,class B>

D_>B& operator,(A const&,B&b)throw() { return(b); }

При чём здесь sequence points я не понял, но код страшный
Re: sequence points
От: Pavel Chikulaev Россия  
Дата: 08.11.05 18:44
Оценка: -1
Здравствуйте, Dmi_3, Вы писали:

D_>Если кто хочет подробнее разобраться с этим то добавьте в свой проект

Спасибо уже сами разобрались

D_>
D_>template<class A,class B>
D_>B&
D_>operator,(A const&,B&b)throw()
D_>{
D_>  return(b);
D_>}
D_>


Стандартный оператор возвращает a...
Re[2]: sequence points
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 09.11.05 08:57
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>Стандартный оператор возвращает a...


Либо я не понял что Вы хотели сказать, либо Вы не правы.
a, b
1. Стандартный оператор вычисляет а, потом идет sequence point, потом вычисляет b и возвращает его
2. Переопределенный оператор вычисляет а и b (порядок вычисления не определен), потом идет sequence point, потом возвращается b.
Re[3]: sequence points
От: Pavel Chikulaev Россия  
Дата: 09.11.05 09:04
Оценка: -1
Здравствуйте, BitField, Вы писали:

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


PC>>Стандартный оператор возвращает a...

BF>
BF>Либо я не понял что Вы хотели сказать, либо Вы не правы.
BF>a, b
BF>1. Стандартный оператор вычисляет а, потом идет sequence point, потом вычисляет b и возвращает его
BF>2. Переопределенный оператор вычисляет а и b (порядок вычисления не определен), потом идет sequence point, потом возвращается b.

откомпиль
int i = 1, j = 2, k;
k = i, j;
cout << k;
Re[4]: sequence points
От: Кодт Россия  
Дата: 09.11.05 09:13
Оценка: 1 (1) :)
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>откомпиль

PC>
PC>int i = 1, j = 2, k;
PC>k = i, j;
PC>cout << k;
PC>


Приоритеты операторов? Расстановка скобок?
(k=i),j versus k=(i,j)
Перекуём баги на фичи!
Re[4]: sequence points
От: korzhik Россия  
Дата: 09.11.05 09:14
Оценка: 1 (1)
Здравствуйте, Pavel Chikulaev, Вы писали:

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


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


PC>>>Стандартный оператор возвращает a...

BF>>
BF>>Либо я не понял что Вы хотели сказать, либо Вы не правы.
BF>>a, b
BF>>1. Стандартный оператор вычисляет а, потом идет sequence point, потом вычисляет b и возвращает его
BF>>2. Переопределенный оператор вычисляет а и b (порядок вычисления не определен), потом идет sequence point, потом возвращается b.

PC>откомпиль

PC>
PC>int i = 1, j = 2, k;
PC>k = i, j;
PC>cout << k;
PC>


Всё таки операттор "запятая" возвращает второй операнд, а здесь выведется единиуа, так как у оператора присваивания приоритет выше.
Re[5]: sequence points
От: Pavel Chikulaev Россия  
Дата: 09.11.05 09:23
Оценка:
Здравствуйте, korzhik, Вы писали:

PC>>откомпиль

PC>>
PC>>int i = 1, j = 2, k;
PC>>k = i, j;
PC>>cout << k;
PC>>


K>Всё таки операттор "запятая" возвращает второй операнд, а здесь выведется единиуа, так как у оператора присваивания приоритет выше.

Туплю...
Re[2]: sequence points
От: Dmi_3 Россия  
Дата: 09.11.05 16:05
Оценка: 222 (19) :))) :))) :))) :)
Здравствуйте, BitField, Вы писали:

>... так что мне не страшно

Может и не страшно...
Но часов 10 МУЧИТЕЛЬНЕЙШЕЙ ОТЛАДКИ было потрачено.

>А почем это так бьет -- по стлю, что ли?


ПЬЕСА "Кошмар программиста"
ужастик в трёх действиях без пролога(не язык) но с эпилогом.

Действие первое:
(if you cannot have the best, make the best of what you have)
Если в первом акте на стене висит ружьё
то в последнем оно выстрелит!(ну очень вольный перевод)

Рядовая контора взялась за многопоточный проект.
Блокировки частенько осуществлялись примерно так:
class lock_resource{...};
...
lock_resource(X), X.do_something();

Способ на троечку с плюсом, но прост как грабли.
Вот эти грабли и по лбу...

Действие второе:
(if you are tired then you'd better stay at home)

Увольнялся человек из конторы. (умница наверно был)
Зарплату последнюю не платили. (зачем? увольняется же)
Плюнул он на зарплату и постарался
сделать super_puper_inline operator,()
что-бы даже в DEBUG-ере туда не попадать.
А ежели и попал то выглядит как безобидное
протоколирование блокировок...

Действие третье:
(to swim like a stone)
Враг вступает в город пленных не щадя.
Потому что в кузнице небыло гвоздя!(ещё более вольный перевод)

Недели через две народ заметил неладное.
Приложение злобно глючило!
Потоки, взявшись за руки, водили хороводы
и время от времени безбожно рвали в клочья общие ресурсы!
Ещё пару недель всем миром искали ошибки.
Сначала искали использование ресурсов без блокировки.
Потом ошибки в многочисленных блокировщиках...
(сколько кода написано! А ещё говорят что
template раздувают код!)
Но больше ругали компилятор, OS, Гей Тса и матерились.
Кажется, начался "переезд" в single-thread.
Жить-то как-то надо.
Может и до сих пор матерились бы...
И это всего лишь какая-то "вшивая" sequence point!

Эпилогwelldoing)
Кстати, за исправление и советы по организации
блокировок тоже не заплатили.
"Нефиг за 30 строчек платить, у нас люди по 10000 пишут!"
Интересно, что и когда у них там опять "стрельнёт"?


А общественности дарю идеи (без реализации).
Т.к. за них не заплатили они не принадлежит конторе,
а критику услышать хочется.
template < class T, class ctritical_section = Ваша_любимая >
//Ресурс разделяемый между потоками.
class shared_resource
{
  typedef shared_resource<T,ctritical_section> self;
  friend class lock<T,ctritical_section>;

  //Может предоставлять дополнительный сервис. см. ниже
  ctritical_section cs;

  //Важно при истинной паралельности. Процессоры не будут "драться".
  //Возможно лучше спрятать это внутри ctritical_section и обеспечить
  //STATIC_ASSERT(sizeof(ctritical_section)%processor_cache_line==0);
  //и размещение ctritical_section по адресам кратным processor_cache_line
  //ctritical_section и data не должны попадать в одну кэш-линию.
  char cache_align[processor_cache_line-1];

  //Без блокировки доступ к data крайне затруднён. Забыть lock невозможно.
  //Можно реализовать в виде private наследования.(учитывайте cache_align)
  //Возможно лучше использовать указатель ctritical_section* cs;
  T data;
  //А кому не лень может даже разложить всё это на стратегии.

public:
  //По умолчанию сгенериться не совсем то что надо.
  //(И зачем Страуструп эти умолчания сделал?)
  self& operator=(self const&);
  explicit//template конструктор НЕ является конструктором копий.
  shared_resource(self const&);
  //Да! lock это smart-pointer
  lock<T,ctritical_section> operator&();
  shared_resource();
  //Передадим аргументы конструктору T
  template<class A>
  explicit
  shared_resource(A const&);
  template<class A,class B>
  shared_resource(A const&,B const&);
  template<class A,class B,class C>
  shared_resource(A const&,B const&,C const&);
  ...
  //Можно и кучку operator-ов добавить.
  operator T()const;//а НЕ operator T const&()const;
  void swap(self&);//Может уменьшать вероятность dead-lock см. ниже
  self& operator=(T const&);
  //и т.д.
  ...
};

//Если конструктор ресурса T использует НЕ const ссылку используйте
template<class T>
class out_argument
{
  T& tmp;
public:
  operator T&() const throw()
    { return tmp; }
  explicit out_argument(T&src) throw()
    : tmp(src) {}
};

//Например если использовать конструктор you_class::you_class(std::istream&);
//то можно написать так:
shared_resource<you_class> object_name(out_argument(std::cin));
//А доступаться с блокировкой так:
(&object_name)->do_something();
access(object_name)->do_something();

template < class T, class ctritical_section = Ваша_любимая >
//Блокирует и предоставляет доступ к ресурсу.
class lock{
  shared_resource<T,ctritical_section>* ptr;
  //Не надо его по new ! Ещё delete забудете!
  void* operator new(size_t);
  //Попрячем это пока. Ежели понадобиться сделаем public
  //Опять же не будет лёгкой возможности lock в другой поток передать.
  //Вдруг я там просто счётчик инкрементирую. Ресурс то уже залочен.
  lock(lock const&);
  lock& operator=(lock const&);//Аналогично.
public:
  ~lock();//Забыть unlock невозможно. И throw не страшны.
  lock(shared_resource<T,ctritical_section>&);
  //Не вызывайте явно: T* ptr = access(X).operator->();
  //Не запоминайте указатель T*
  //Внутри T::any_method() не запоминайте this;
  T* operator->()const throw();
  T& operator* ()const throw();//Не запоминайте ссылку!
  //можно и так:
  lock& operator=(class non_complete*);//Снимем блокировку так: access_ptr=0;
  //далее кто как хочет и умеет:
  ...
};

//Ну и это для удобства. Не писать же везде lock<my_type>(my_object)
template<class T>
typename lock<T>
access(shared_resource<T>&src)
{
  return lock<T>(src);
}


Если в критической секции ведётся протоколирование lock\unlock
то можно детектировать ПОТЕНЦИАЛЬНЫЕ dead-lock
когда различен порядок lock (без unlock) в РАЗНЫХ потоках.
поток X: ... lock(A) ... lock(B) <dead-lock> ... unlock(B) ... unlock(A) ...
поток Y: ... lock(B) ... lock(A) <dead-lock> ... unlock(A) ... unlock(B) ...
Это, конечно, не гарантирует их полного отсутствия
но практически очень удобно, выявляет тонкие логические
несуразности и позволяет иерархически группировать
и ассоциировать ресурсы с critical_section.
В этом смысле swap можно реализовать примерно так
void swap(T&a,T&b){
  //Важен одинаковый порядок блокировок.
  if(compare_critical_section_id(a,b){//ID могут быть просто адресами.
    std::swap(a,b);
  }else{
    std::swap(b,a);
  }
}

УФ! Упарился! Хватит.
Надеюсь, что эти идеи помогут тем кто не гониться за объёмами кода,
а пьеса объяснит некоторым работодателям как оно в жизни бывает.
Re[3]: sequence points
От: Глеб Алексеев  
Дата: 09.11.05 16:57
Оценка:
Здравствуйте, Dmi_3.

Я полностью в коде не разобрался, но не лучше ли вместо перегрузки оператора & перегрузить оператор ->? О таком подходе и Александреску, и Страуструп упоминали.
Re[4]: блокировки
От: Dmi_3 Россия  
Дата: 09.11.05 22:24
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>Здравствуйте, Dmi_3.


ГА>... но не лучше ли вместо перегрузки оператора & перегрузить оператор ->?


Это зависит от того хотим ли мы ЯВНО видеть потенциально долгие блокировки.
Безусловно X->do_something(); проще чем access(X)->do_something();
Перефразируя можно сказать: Делайте Ваши программы максимально простыми, но не проще чем необходимо.
Ситуация немного напоминает классическое приведение типов и _cast
Re[3]: sequence points
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.11.05 08:20
Оценка: 4 (2) +1
Здравствуйте, Dmi_3, Вы писали:

D_>Рядовая контора взялась за многопоточный проект.

D_>Блокировки частенько осуществлялись примерно так:
D_>
D_>class lock_resource{...};
D_>...
D_>lock_resource(X), X.do_something();
D_>

D_>Способ на троечку с плюсом, но прост как грабли.
D_>Вот эти грабли и по лбу...

А вы, я смотрю, любите компилятор напрягать по полной программе (начало было положено в теме Compile-time вычисления: а оно вообще надо?
Автор: eao197
Дата: 25.10.05
, конкретно в Re[7]: Compile-time вычисления: а оно вообще надо?
Автор: Dmi_3
Дата: 26.10.05
).

Казалось бы, причем здесь KISS?

D_>Действие второе:

D_>(if you are tired then you'd better stay at home)

D_>Увольнялся человек из конторы. (умница наверно был)

D_>Зарплату последнюю не платили. (зачем? увольняется же)
D_>Плюнул он на зарплату и постарался
D_>сделать super_puper_inline operator,()
D_>что-бы даже в DEBUG-ере туда не попадать.
D_>А ежели и попал то выглядит как безобидное
D_>протоколирование блокировок...

Из той же оперы. Казалось бы, куда проще (вместо ACE, имхо, можно взять любую библиотеку с поддержкой потоков):
ACE_Thread_Mutex lock;
...
ACE_Guard< ACE_Thread_Mutex > scoped_guard< lock >;
// Твори с ресурсом все, что захочу.


ан нет, хотелось покруче и покрасивши. Особенно при отладке. Когда выяснилось, что сопровождать сложный красивый код не кому.

D_>Действие третье:

D_>(to swim like a stone)
D_>Враг вступает в город пленных не щадя.
D_>Потому что в кузнице небыло гвоздя!(ещё более вольный перевод)

Интересный код. Правда оценить, насколько он удобен в реальном использовании не берусь. Не приходилось мне разрабатывать классов, которые не содержали бы в себе защиты от многопоточности, но которые бы использовались бы в многопоточной программе через такие хитрые lock-обертки. Иногда, одним mutex-ом приходится защищать сразу несколько ресурсов. Иногда разрабатывается thread-safe класс, который внутри себя содержит mutex и сам захватывает его внутри собственных методов. Тогда нет проблем с тем, что результат lock::operator*() нельзя сохранять. А еще класс с собственным mutex-ом внутри может быть удобен при использовании single-writter/multi-reader блокировок. Например, const-методы захватывают mutex в read-only блокировке, а не-const методы -- в write-only блокировке.

В общем,

Simplicity does not precede complexity, but follows it.

EPIGRAMS IN PROGRAMMING
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: sequence points
От: rus blood Россия  
Дата: 10.11.05 10:33
Оценка: :))
Здравствуйте, Dmi_3, Вы писали:


D_>Эпилогwelldoing)

D_>Кстати, за исправление и советы по организации
D_>блокировок тоже не заплатили.
D_>"Нефиг за 30 строчек платить, у нас люди по 10000 пишут!"
D_>Интересно, что и когда у них там опять "стрельнёт"?

А ты им что-нить оставил?
Имею скафандр — готов путешествовать!
Re[4]: блокировки
От: Dmi_3 Россия  
Дата: 11.11.05 16:11
Оценка:
Здравствуйте, eao197, Вы писали:

E_>А вы, я смотрю, любите компилятор напрягать по полной программе…

Да! И это гораздо лучше, чем напрягать коллег тем, что им приходиться не забыть вызвать lock\unlock или(что лучше) создавать объект-блокировщик в функциях-членах. Приведённый вариант с template приводит к более быстрой компиляции чем код исходно использовавшийся в конторе. (Существенное время компиляции занимает ввод и разбор лексем, а их число стало на 4 (двоичных) порядка меньше.) Это экономит МОЁ время, а от того как нагреется при этом процессор я абстрагируюсь. Там где время компиляции может меня(а не компилятор) не устроить я предпринимаю специальные меры. В частности делаю программу более дружественной и защищённой от ошибок, что позволяет уменьшить частые перекомпиляции. Все-таки хочется заботиться о человеке больше, чем о железках и\или битиках программы.

E_>Из той же оперы. Казалось бы, куда проще (вместо ACE, имхо, можно взять любую библиотеку с поддержкой потоков):

E_>ACE_Thread_Mutex lock;
E_>...
E_>ACE_Guard< ACE_Thread_Mutex > scoped_guard< lock >;
E_>// Твори с ресурсом все, что захочу.

E_>ан нет, хотелось покруче и покрасивши. Особенно при отладке. Когда выяснилось, что сопровождать сложный красивый код не кому.
Я с трудом понимаю что Вы хотите сказать(не знаком с ACE) да и согласовать приведённые русские фразы для меня сложно. По моему мнению:
ACE_Guard< ACE_Thread_Mutex > scoped_guard< lock >;

1) Не является правильной семантической конструкцией для блокировки (боюсь, что даже сделать это правильной синтаксической конструкцией трудно).
2) Их код трудно назвать сложным и красивым.(…прост как грабли…)
3) Они решали задачу (не вполне адекватными методами), а не пытались покруче и покрасивши. Я тоже не ставил себе такую цель. Просто, проведя анализ проблем, возникающих в их коде попытался найти более адекватное решение.
4) Отсутствие operator,() и блокировок в списке инициализаторов конструктора (что иногда нужно) равно как и ЛЮБАЯ технология в рамках C++ не поможет от злонамеренной порчи программы. Он бы использовал связку #define \ template и\или нарушение ODR. Это приведёт к аналогичным эффектам. Подробнее могу сообщить ТОЛЬКО приватно, если будет понятно, как блокируются ресурсы в Вашем проекте. Но лучше проверьте мне на слово.
5) Использование синтаксиса с operator,() вне списка инициализаторов конструктора удобно тем, что не приходиться придумывать бредовое имя для локера(с возможным warning о его неиспользуемости и исчезновением блокировок при агрессивной оптимизации) и расставлять скобки {} для снятия блокировки. Это не относится к моему варианту т.к.
а) Не нужен operator,() используется operator->()
b) Бредовое имя начинает именовать ИСПОЛЬЗУЕМЫЙ интерфейс доступа к ресурсу.
c) Вместо расстановки скобок{} можно написать. access_ptr=0; и освободить ресурс.

E_>Иногда, одним mutex-ом приходится защищать сразу несколько ресурсов. Иногда разрабатывается thread-safe класс, который внутри себя содержит mutex и сам захватывает его внутри собственных методов.

Каждый подход (даже используемый в конторе) может найти своё применение.
Бесспорным достоинством Вашего подхода является то, что
E_>… нет проблем с тем, что результат lock::operator*() нельзя сохранять.
Я был бы благодарен, если Вы сообщите примеры, где это можно широко использовать.
Но, похоже, что это единственное преимущество.
//Позволяет специализировать поведение для некоторых типов.
//В частности использовать interlocked_functions и т.д.
template < class T, class locker >
class shared_resource
{
//Позволяет использовать некоторые типы сторонних библиотек и встроенные типы.
  T data;
//Позволяет во время исполнения ассоциировать блокировщик для ресурса.
//и легко менять стратегии блокировок.
//(one_section \ section_per_class \ section_per_object \ mutex и т.д.
  locker* lock;
};


E_>А еще класс с собственным mutex-ом внутри может быть удобен при использовании single-writter/multi-reader блокировок. Например, const-методы захватывают mutex в read-only блокировке, а не-const методы -- в write-only блокировке.

Я бы (в большинстве случаев) отнёс ранний выбор стратегии захвата к недостаткам метода, препятствующим повторному использованию класса.
Как я уже говорил ситуация напоминает _cast:
//Выбираем тип доступа только при использовании, а не при написании класса.
full_access(X)->do();
//Аналог const_cast
read_access(X)->do_const();//Это read-only блокировка
//Аналог static_cast
lock_base_only<base_X>(X)->base_X::non_virtual_method();
//Аналог dynamic_cast (в смысле наличия исключения)
access_with_exception<already_locked>(X)->do();
access_with_exception<time_expered>(X,12*second)->do();
//И даже аналог reinterpret_cast
access_without_lock(X)->do();

Можно предложить и расширения, автоматически выбирающие способ доступа в зависимости от сигнатуры метода. Но всё это ТОЛЬКО если задача требует, а в простых случаях – можно просто как говорил Глеб Алексеев: X->do(); Я предпочитаю access(X)->do();

P.S.
Существуют и другие недостатки как моего, так и Вашего методов. О них могу сообщить позже.
Offtopic
С коммерческой точки зрения Ваш подход вполне оправдан. Пользователь получив готовый проект отвечающий спецификации но чем-то его не удовлетворяющий, закажет новый проект оплатив по полной программе его разработку(которую придётся проводить с середины). В моём случае изготовление второго проекта могло бы быть быстрее и обойтись дешевле (за счёт большей гибкости и повторной используемости кода), но пользователь об этом не знает, да и программистам это не выгодно.
Re[5]: блокировки
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.11.05 17:52
Оценка:
Здравствуйте, Dmi_3, Вы писали:

E_>>А вы, я смотрю, любите компилятор напрягать по полной программе…

D_>Да! И это гораздо лучше, чем напрягать коллег тем, что им приходиться не забыть вызвать lock\unlock или(что лучше) создавать объект-блокировщик в функциях-членах. /.../ Все-таки хочется заботиться о человеке больше, чем о железках и\или битиках программы.

Так-то оно так. Просто я для себя пришел к выводу, что сложный код, который использует максимум возможностей и тонкостей языка, приводит, как минимум, к двум проблемам:

1. Невозможность компиляции или неправильное поведение программы на менее "продвинутом" компиляторе. Сейчас уже не так актуально, хотя здесь проскакивают вопросы о причинах internal compiler error. А раньше это бывало сплошь и рядом на шаблонных конструкциях. Или вот еще, помню, как мне пришлось году эдак в 95-м или 96-м изменить дизайн программы из-за того, что имевшаяся в моем распоряжении версия GNU C++ под RedHat Linux не перехватывала в catch объекты-исключения производных классов. А на Symbian OS, как и сейчас, оказывается, нормальных C++ исключений нет (Программирование под Symbian OS: начало
Автор: Дмитрий Москальчук
Дата: 12.07.05
).

2. Изощренно хитрые конструкции могут выглядеть красиво для меня, но совсем не для моего колеги или, что хуже, пользователя. И, что забавно, спустя какое-то время, мне самому становится тяжело в этом коде разбираться.

Поэтому сейчас я стараюсь не использовать код, который не становится понятным и очевидным после 5-10 минутного изучения. Ваш код, к сожалению, находится на грани фола. Т.е. понять его можно и без особых проблем, но для этого требуется некоторое время и напряжение. А для меня это уже показатель, что что-то не так.

E_>>ан нет, хотелось покруче и покрасивши. Особенно при отладке. Когда выяснилось, что сопровождать сложный красивый код не кому.

D_>Я с трудом понимаю что Вы хотите сказать(не знаком с ACE)

The ADAPTIVE Communication Environment -- очень продвинутая библиотека для большого количества низкоуровневых, системных вещей. Жаль, что не очень популярная у нас. Хотя, к счастью, две книги про ACE на русский уже переведены (Документация по ACE
Автор: Сергей
Дата: 25.10.05
).

D_> да и согласовать приведённые русские фразы для меня сложно.


Дык эта, пa-русскi пишу с абшыбками

D_> По моему мнению:

D_>
D_>ACE_Guard< ACE_Thread_Mutex > scoped_guard< lock >;
D_>

D_>1) Не является правильной семантической конструкцией для блокировки (боюсь, что даже сделать это правильной синтаксической конструкцией трудно).

Это точно. Скобки-то я и перепутал:
ACE_Guard< ACE_Thread_Mutex > scoped_guard( lock );


D_>4) Отсутствие operator,() и блокировок в списке инициализаторов конструктора (что иногда нужно) равно как и ЛЮБАЯ технология в рамках C++ не поможет от злонамеренной порчи программы. Он бы использовал связку #define \ template и\или нарушение ODR. Это приведёт к аналогичным эффектам. Подробнее могу сообщить ТОЛЬКО приватно, если будет понятно, как блокируются ресурсы в Вашем проекте. Но лучше проверьте мне на слово.


На форуме трудно верить на слово
Я вот думал, что привел корректный код scoped_guard, а оказалось...

D_>5) Использование синтаксиса с operator,() вне списка инициализаторов конструктора удобно тем, что не приходиться придумывать бредовое имя для локера(с возможным warning о его неиспользуемости и исчезновением блокировок при агрессивной оптимизации) и расставлять скобки {} для снятия блокировки. Это не относится к моему варианту т.к.


А вот эту тему можно раскрыть подробнее?

D_>а) Не нужен operator,() используется operator->()

D_>b) Бредовое имя начинает именовать ИСПОЛЬЗУЕМЫЙ интерфейс доступа к ресурсу.

Здесь так же не совсем понятно.

D_>c) Вместо расстановки скобок{} можно написать. access_ptr=0; и освободить ресурс.


E_>>Иногда, одним mutex-ом приходится защищать сразу несколько ресурсов. Иногда разрабатывается thread-safe класс, который внутри себя содержит mutex и сам захватывает его внутри собственных методов.

D_>Каждый подход (даже используемый в конторе) может найти своё применение.
D_>Бесспорным достоинством Вашего подхода является то, что
E_>>… нет проблем с тем, что результат lock::operator*() нельзя сохранять.
D_>Я был бы благодарен, если Вы сообщите примеры, где это можно широко использовать.

Вообще-то у меня совсем другой подход. Не знаю, как широко его можно использовать, но заключается он в том, чтобы свести количество объектов, которые разделяются между потоками к минимуму. У нас вообще используется фрейморк для мультипоточного (да и не только) программирования, в котором объекты работают в собственных потоках, даже не зная о том, что есть другие потоки. А межпотоковое взаимодействие строится на обмене сообщениями. В результате работать с разделяемыми объектами приходится настолько редко, что использовать обычный scoped_lock совершенно не обременительно. Более того, его использование тривиально, хорошо понятно и заметно.

Чтобы не быть голословным, в моем проекте ObjESSty
Автор: eao197
Дата: 24.01.05
всего пять упоминаний ACE_Guard на более чем пятьдесят тысяч строк кода. А ведь ObjESSty предоставляет и thread-safe классы. А в вышеупомянутом фреймворке -- 60 на сорок пять тысяч строк, и это притом, что там как раз ведется управление многопоточностью.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: sequence points
От: remark Россия http://www.1024cores.net/
Дата: 11.11.05 18:31
Оценка: :)
Здравствуйте, Dmi_3, Вы писали:


А уж что с макросами можно придумать...

Типа:

#undef SetWindowText
#define SetWindowText(x) SetWindowTextA("Я ВАС НЕНАВИЖУ")





Хотя, конечно, что б не заметили, надо что-нить более незаметное, типа:


#undef Sleep
#define Sleep(x) Sleep(x+1000)






Пусть недоумевают, что случилось с планировщиком ОС


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.