Здравствуйте, PowerUserX, Вы писали:
PUX>Почему В STL почему нет аналога Event Objects(Win32)?
ИМХО потому что нет реализации в ядре систем, на которые пришлось все же ориентироваться.
Contrary to popular belief, event objects – a construct particular to MS Windows and not found in *NIX OS:es – are useful in many instances where exact thread execution control is needed. For instance, you may want to have a thread pausing itself while starting another one.
However, if you post a question on a *NIX forum about how to implement event objects or something similar, you will likely get an answer along the lines of “just use mutexes”. Unfortunately, there is no “just” about it. Implementing event objects is a bit tricky, as there are several instances where race conditions or deadlocks can occur.
Кстати, в ядре Windows есть еще специальный объект EventPair, для которого можно атомарно дождаться одного ивента пары и установить другой ивент, но в Win API он не экспонируется, только через ntdll.dll
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, fdn721, Вы писали:
F>>СRITICAL_SECTION штука то хитрая, это гибридный приметив синхронизации. Который по большей части работает в UserSpace и только когда возникает долгое ожидание ресурса происходит вызов в KernelSpace и ожидается освобождение ресурса.
BZ>а std::unique_lock<std::mutex> — это не то?
По использованию — да, по быстродействию — нет.
std::mutex внутри себя использует объект ядра. Любая попытка захватить std::mutex влечёт вызов в ядро. Вызов в ядро это очень дорогостоящая операция, требующая около 1000 инструкций.
У СRITICAL_SECTION будет вызов в ядро, только когда будет длительная попытка захватить уже захваченную кем-то СRITICAL_SECTION.
U>в качестве альтернативы предлагают использовать condition_variable + mutex
А мне эта связка не нравится. Очень легко допустить ошибку и явный overkill в простых случаях. Чаще всего то что делают с помощью condition+mutex можно сделать через boost::barrier. Что-то вроде:
Здравствуйте, dead0k, Вы писали:
D>Здравствуйте, PowerUserX, Вы писали: PUX>> только cond_var
D>У которого есть wait_for/wait_until. D>Чего не хватает?
Быстро написал
имел ввиду что есть mutex b cond_var
а хотел бы event c методами типа wait b wait_time_for
Re[2]: В STL почему нет аналога Event Objects(Win32)
Спасибо за ссылки, стало понятнее, как на condition_variable эмулировать event.)
Но все равно осталось непонятным, почему кроссплатформенные библиотеки не реализуют такой удобный примитив синхронизации, как event: первая Ваша ссылка очень наглядно демонстрирует, насколько код с event проще и понятнее.) В чем именно состоят идеологические дефекты event'а? Подозреваю, что stl, QT и другие кроссплатформенные библиотеки не используют аналога виндового события потому, что на юниксе его сложно реализовать.)
Re[3]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, jahr, Вы писали:
J>В чем именно состоят идеологические дефекты event'а? Подозреваю, что stl, QT и другие кроссплатформенные библиотеки не используют аналога виндового события потому, что на юниксе его сложно реализовать.)
я бы предположил, что связка cond_var + mutex более мощная, нежели Event. последний может быть реализован с помощью первых двух
так что с реализацией на линуксе проблем не будет
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Implementing event objects is a bit tricky, as there are several instances where race conditions or deadlocks can occur. PD>http://win32eoposix.sourceforge.net/
тут основная сложность в реализации WaitForMultipleObjects, которая далеко не всегда нужна. без нее все должно быть просто (по прикидкам)
Re[2]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, PowerUserX, Вы писали:
PUX>>Почему В STL почему нет аналога Event Objects(Win32)?
PD>ИМХО потому что нет реализации в ядре систем, на которые пришлось все же ориентироваться.
CCore замечательно работает и поверх Windows, и поверх Linux.
Здравствуйте, Шахтер, Вы писали:
Ш>CCore замечательно работает и поверх Windows, и поверх Linux.
Ну и что ? Посмотри ссылку, которую я привел, там как раз моделирование ивентов с помощью мютексов. Я же не говорю, что сделать нельзя. Я просто думаю, что в виду того, что ивенты ядром линукса не поддерживаются, авторы STL решили их не включать. Моделируйте сами как хотите.
With best regards
Pavel Dvorkin
Re[2]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, PowerUserX, Вы писали:
CS>Наверное потому что такой примитив добавить тривиально можно, как-то так:
CS>
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, PowerUserX, Вы писали:
CS>Наверное потому что такой примитив добавить тривиально можно
можно
CS>как-то так
ну далековато от истины. лучше см. код B0FEE664
Re[2]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, PowerUserX, Вы писали:
CS>Наверное потому что такой примитив добавить тривиально можно, как-то так:
CS>
Абсолюьно неправильная реализация :
Во-первых, wait может сработать просто так (фантомные просыпания).
Во-вторых, если один поток сделает notify_one а второй не будет сидеть в этот момент на wait, то событие уйдет в небытие. О нем никто никогда не узнает.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Шахтер, Вы писали:
Ш>>CCore замечательно работает и поверх Windows, и поверх Linux.
PD>Ну и что ? Посмотри ссылку, которую я привел, там как раз моделирование ивентов с помощью мютексов. Я же не говорю, что сделать нельзя. Я просто думаю, что в виду того, что ивенты ядром линукса не поддерживаются, авторы STL решили их не включать. Моделируйте сами как хотите.
Это называется упражнение в телепатии.
Как причина -- идиотская. В ядрах и не должно быть реализации всех мыслимых типов синхронизирующих объектов. Должен быть достаточный базис, позволяющий реализовывать их в приложениях.
STL -- это не библиотека поддержки операционной системы. По задумке, это библиотека программирования общего назначения, предназначенная для облегчения рутинных вещей для программиста.
И как таковая она должна содержать в том числе и широкий набор примитивов синхронизации, предоставляя удобный общий интерфейс для их использования и избавляя программиста от необходимости вникать в нюансы операционной системы.
Например, библиотека fstream скрывает детали низкоуровневой работы с файлами. В Windows мы вызываем функции ReadFile/WriteFile для чтения/записи в файл, а в Linux read/write.
Используя стандартную библиотеку, можно абстрагироваться от этого и писать переносимый код.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>объекты синхронизации в C++ сделаны по образцу posix api. так что правильный подход — осваивать condition variables и писать алгоритмы под них
Егор (или кто ещё знает) — в чём я ошибаюсь?
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, Шахтер, Вы писали:
Ш>Это называется упражнение в телепатии.
Мы начинаем скатываться в ФП, если не в КСВ
Ш>Как причина -- идиотская. В ядрах и не должно быть реализации всех мыслимых типов синхронизирующих объектов. Должен быть достаточный базис, позволяющий реализовывать их в приложениях.
Теоретически да. Практически же имеют место всякие привходящие обстоятельства, которые играют роль при разработке той или иной библиотеки. Называть такие решения идиотскими я бы не стал.
Я никогда не занимался вопросом, какой именно набор синхрообъектов является базисом, на основе которого можно сделать любую синхронизацию. Наверное, на этот счет есть какая-то теория. В частности, тот же мютекс в Win API — это лишь двоичный семафор, правда, с несколько измененнным поведением (кстати, из-за этого в ядре его называют mutant).
MS в Win API , по-видимому, решила сделать все возможные виды синхрообъектов, не заботясь об их минимальном наборе.
Кстати, аналогичное имело место в том, что касается языков програмирования. В годы моей программистской молодости были 2 термина : язык-ядро (тщательно отобранный набор ортогональных средств, ничего дублирующегося), и язык-оболочка (вали в кучу все, что придумаешь, пусть программист потом берет то, что хочет). И те, и другие существовали.
Ш>STL -- это не библиотека поддержки операционной системы. По задумке, это библиотека программирования общего назначения, предназначенная для облегчения рутинных вещей для программиста.
+1
Ш>И как таковая она должна содержать в том числе и широкий набор примитивов синхронизации, предоставляя удобный общий интерфейс для их использования и избавляя программиста от необходимости вникать в нюансы операционной системы. Ш>Например, библиотека fstream скрывает детали низкоуровневой работы с файлами. В Windows мы вызываем функции ReadFile/WriteFile для чтения/записи в файл, а в Linux read/write. Ш>Используя стандартную библиотеку, можно абстрагироваться от этого и писать переносимый код.
Вполне согласен. Можно еще 100500 примеров привести. И тем не менее порой при разработке библиотек принимают во внимание потенциальную возможность реализации на разных платформах. К примеру, как быть с библиотекой оконнного интерфейса или графики ? В стандарте С++ их нет, а работа с окнами и графикой не менее важна, чем работа с файлами. Ответ прост — да поможет бог тому, кто решится это дело стандартизовать. Существующие реализации (тот же Qt) относительно переносимы, но сделать их стандартом едва ли возможно.
Кстати, о файлах. Современная концепция работы с файлами на нижнем уровне (файл есть бесструктурный набор байтов, в котором возможно позиционирование) родом из Unix. С++ (через С) родом оттуда же. Оттуда это перекочевало в MS-DOS и Windows. Сейчас эта концепция — стандарт де-факто, и большинство здесь присутствующих едва ли предполагает, что может быть иначе. А может, точнее, могло. В OS 360/370 на уровне ядра поддерживались понятия файлов последовательного доступа, прямого доступа, индексно-последовательные файлы, виртуально-последовательные файлы. И в Фортране и ПЛ/1 были особые средства для работы с каждым из этих видов файлов. Этого сейчас у нас нет, и слава богу, так как все это, как стало позже понятно, можно делать и не на уровне ядра. А если бы это сохранилось (кстати, не исключаю, что в нынешних наследниках OS/360 это и до сих пор есть)? Тогда бы авторы С++ (и все прочих языков) имели бы хорошую головную боль насчет поддержки этих возможностей в языке. Не поддерживать — значит, язык не дает возможности работать с приличным куском базового ПО OS/360. Поддерживать — значит писать эмулятор этого для *Nix, а оно надо ?
Здравствуйте, fdn721, Вы писали:
F>Меня вот больше интересует, почему в STL/BOOST нет лёгких примитивов синхронизации, типа виндового CRITICAL_SECTION?
std::atomic_flag это из другой оперы. Больше на InterlockedExchange похоже.
СRITICAL_SECTION штука то хитрая, это гибридный приметив синхронизации. Который по большей части работает в UserSpace и только когда возникает долгое ожидание ресурса происходит вызов в KernelSpace и ожидается освобождение ресурса.
В STL/BOOST таких примитивов почему-то нет. А везде совать std::mutex излишне накладно.
Re[4]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, fdn721, Вы писали:
F>std::atomic_flag это из другой оперы. А везде совать std::mutex излишне накладно.
Там же по ссылке есть пример:
A spinlock mutex can be implemented in userspace using an atomic_flag
F>СRITICAL_SECTION штука то хитрая, это гибридный приметив синхронизации. Который по большей части работает в UserSpace и только когда возникает долгое ожидание ресурса происходит вызов в KernelSpace и ожидается освобождение ресурса.
Насколько я знаю, в линуксе мьютекс тоже вначале спинлочится и только потом уходит в полноценное ожидание.
Здравствуйте, fdn721, Вы писали:
F>СRITICAL_SECTION штука то хитрая, это гибридный приметив синхронизации. Который по большей части работает в UserSpace и только когда возникает долгое ожидание ресурса происходит вызов в KernelSpace и ожидается освобождение ресурса.
а std::unique_lock<std::mutex> — это не то?
Люди, я люблю вас! Будьте бдительны!!!
Re[6]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я никогда не занимался вопросом, какой именно набор синхрообъектов является базисом, на основе которого можно сделать любую синхронизацию. Наверное, на этот счет есть какая-то теория.
таких базисов куча. начиная от семафоров и кончая потоками сообщений. в частнгости, win api и api предоставляю.т два разных базхиса — в winapi нет condition vars
PD>В OS 360/370 на уровне ядра поддерживались понятия файлов последовательного доступа, прямого доступа, индексно-последовательные файлы, виртуально-последовательные файлы.
в createfile тоже есть подобные флаги. а вот в C++ их поддержки нет и я не могу например открыть временный файл, который удалится сразу после закрытия
указание типа файла нужно для оптимизации работы ОС с ним. представляя файл неструктурированным потоком байт с проихвольным доступом, ты делаешь эту оптимизацию дороже
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, fdn721, Вы писали:
F>std::mutex внутри себя использует объект ядра.
Правда-правда?
Это так в стандарте написано? Дескать std::mutex обязан использовать объект ядра?
Re[6]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, fdn721, Вы писали:
F>>>СRITICAL_SECTION BZ>>а std::unique_lock<std::mutex> — это не то? F>По использованию — да, по быстродействию — нет.
просто в C++11 есть unique_lock, а есть какой-то более общий, и у меня создалось впечаптление что unique_lock сильно ограничен в возможностях как раз из-за своей реализации. а что там можно упростить в реализации?
F>Почитайте Рихтера, у него всё подробно расписано.
у него есть книги по C++ 11?
Люди, я люблю вас! Будьте бдительны!!!
Re[7]: В STL почему нет аналога Event Objects(Win32)
[спекуляции про быстродействие СRITICAL_SECTION и std::mutex пропущены]
BZ>просто в C++11 есть unique_lock, а есть какой-то более общий, и у меня создалось впечаптление что unique_lock сильно ограничен в возможностях как раз из-за своей реализации. а что там можно упростить в реализации?
Насколько я помню, есть lock_guard, unique_lock (для std::mutex) и shared_lock (для std::shared_mutex). И основное отличие unique_lock от lock_guard — это возможность сделать lock/unlock явно, тогда как lock_guard это чистая RAII обертка, чтобы захватить мутекс в конструкторе и освободить в деструкторе. shared_lock немного из другой темы и используется для захвата RW-мутексов.
F>>Почитайте Рихтера, у него всё подробно расписано. BZ>у него есть книги по C++ 11?
BZ>таких базисов куча. начиная от семафоров и кончая потоками сообщений. в частнгости, win api и api предоставляю.т два разных базхиса — в winapi нет condition vars
То же самое. Есть в Win32, но нельзя ручаться, что есть везде.
BZ>указание типа файла нужно для оптимизации работы ОС с ним. представляя файл неструктурированным потоком байт с проихвольным доступом, ты делаешь эту оптимизацию дороже
Я немного о другом говорил, сказав про OS/360. Я имею в виду не методы доступа к файлу, а только его организацию. Организация же сейчас только одна — неструктурированный набор байт. А вот в OS/360 были другие виды организации. С индексно-последовательными файлами, например, из Фортрана вообще нельзя было работать, только из ПЛ/1, а с файлами прямого доступа надо было работать другими операторами (DEFINE FILE), чем с файлами последовательного доступа. Они на диске были по другому организованы.
With best regards
Pavel Dvorkin
Re[6]: В STL почему нет аналога Event Objects(Win32)
Здравствуйте, fdn721, Вы писали:
F>std::mutex внутри себя использует объект ядра. Любая попытка захватить std::mutex влечёт вызов в ядро. Вызов в ядро это очень дорогостоящая операция, требующая около 1000 инструкций.
F>У СRITICAL_SECTION будет вызов в ядро, только когда будет длительная попытка захватить уже захваченную кем-то СRITICAL_SECTION.