На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Мьютексы С++11, С++14, С++17 , Нужно разобраться - кто и что из себя представляет.
    Всем привет!

    Возник такой вопрос - вот в std есть куча мьютексов на выбор(вроде в C++14'ом стандарте их 4 - mutex, recursive_mutex, и два таких же с префиксом timed,), меня интересуют ровно два типа мьютексов - std::mutex и std::recursive_mutex.
    Каково их принципиальное отличие, на уровне ОС Windows?
    Да, рекурсивный мьютекс очень сильно напоминает CRITICAL_SECTION. Но как я погляжу везде и всюду все используют std::mutex.
    При этом если сравнивать конкретно Windows синхронизацию, то из книги того же Рихтера, очевидно что Mutex - это объект ядра Windows, а значит ему постоянно приходится переключаться из User Mode в Kernel Mode, что очень медленно, при этом CRITICAL_SECTION - реализована на основе interlocked функций, что существенно повышает производительность(Так как не нужно постоянно переходить в kernel mode).

    У меня давно возник вопрос - как реализованы мьютексы в пространстве -> std, для той же Windows(есть ли какие нибудь ремарки для них специфичные)? Есть ли об этом в стандарте какие то оговорки?
    Допустим я пишу какой то критичный по производительности паралельно-выполняющийся алгоритм, и при этом использую std::mutex, какие преимущества я получу, если заменю std::mutex на std::recursive_mutex? При этом, мне не нужно его захватывать больше 1-го раза. И есть ли смысл вообще использовать std::recursive_mutex, если я не хочу его захватывать больше 1 раза?
    Так же интересует, вдруг мне нужна блокировка на уровне ядра? Я ведь правильно понимаю что для этого нужно использовать обычный std::mutex?

    Выводы:
    Правильно ли я понимаю что:
    std::mutex - Windows mutex - медленный, переключающийся в kernel mode
    std::recursive_mutex - CRITICAL_SECTION - быстрый, по сравнению с обычным виндовым мьютексом.
    ???

    Отсылки к конкретным пунктам стандарта - очень сильно приветствуются. Спасибо за пояснения.
    Сообщение отредактировано: Wound -
      Цитата Wound @
      Отсылки к конкретным пунктам стандарта - очень сильно приветствуются. Спасибо за пояснения.

      Не думаю, что это можно будет найти в Стандарте.
      Речь же идет о "реализации" - ее и нужно копать.
      Или уже кем-то раскопанное читать, либо самому исследовать исходники STL.

      Линк
        Цитата JoeUser @
        Не думаю, что это можно будет найти в Стандарте.
        Речь же идет о "реализации" - ее и нужно копать.
        Или уже кем-то раскопанное читать, либо самому исследовать исходники STL.

        Фишка основная, которая послужила целью к созданию этой темы, такая -> Вот есть Мьютексы, объекты ядра, и есть Критические секции - не объекты ядра. Первые могут лочить потоки глобально для параллельных процессов, вторые локально - для потоков в рамках одного процесса. Какую структуру данных мне нужно юзать из нового стандарта, чтобы залочить ресурс, использующийся между разными процессами? И будет ли профит, если вдруг я пишу узконаправленное приложение, которое должно обойтись критической секцией, и использую при этом std::recursive_mutex, вместо std::mutex?

        ИМХО без этого знания - я не могу писать кросплатформенное приложение и опираться на стандартную библиотеку STL. Я хочу выяснить для себя - могу я на нее полагаться при кросплатформенном программировании или нет.

        Добавлено
        Если это все оставленно на откуп, то в этом случае std::mutex и std::recursive_mutex могут быть реализованы через критические секции, тогда решая задачу, где мне нужно залочить ресурс между процессами - я внезапно для себя, могу выяснить, что зря я тут юзал std::mutex. А этого бы не хотелось. Хочется каких то гарантий происходящего.
        Сообщение отредактировано: Wound -
          Wound, повторюсь - твой вопрос вполне понятен.
          Стандарт не регламентирует реализацию.
            Цитата JoeUser @
            Стандарт не регламентирует реализацию.

            Ты уверен в этом? Можешь привести раздел стандарта, говорящего об этом?
            Я имею ввиду конкретно мьютексы.

            Добавлено
            Дело в том, что я для себя хочу окончательно этот вопрос решить. И фразы, даже сказанные в повелительном или повествовательном или в финальном тоне - меня не устраивают. Их можно интерпретировать как - Это твое ИМХО.
            Я же хочу объективности. По возможности. Пусть даже без цитирования стандарта, но с пояснением - почему так.
            Сообщение отредактировано: Wound -
              Цитата Wound @
              Ты уверен в этом? Можешь привести раздел стандарта, говорящего об этом?
              Я имею ввиду конкретно мьютексы.

              Уверен. Вообще-то для меня будет откровением если ты приведешь материал из Стандарта, где вообще упоминается M$ Windows, применительно к любому разделу/теме.

              Лучче поищи дискуссии типа этой.
              Там как раз обсуждаются реализации.
                Меня интересует конкретно вопрос - std::mutex - очень часто и везде используется, в 95% хелпах, гуглах и остального ты встретишь именно std::mutex. Вопрос - он реализован как критическая секция или нет?
                Если он реализован как виндовый Мьютекс, и постоянно лезет в kernel mode - то какой смысл его вообще использовать?
                Вот мой основной вопрос.
                А вот std::recursive_mutex очень сильно похож на критическую секцию. Но возникает вопрос - чем std::mutex тогда лучше? Я хочу гарантированного быстродействия, стоит ли мне для этого набирать слово recursive_ или можно обойтись std::mutex, что короче в наборе по крайней мере букв?
                  Хотя вот предисловие к последнему стандарту C++17:
                  Цитата
                  ISO/IEC 14882:2017 specifies requirements for implementations of the C++ programming language. The first such requirement is that they implement the language, so this document also defines C++. Other requirements and relaxations of the first requirement appear at various places within this document.


                  Как видишь - регламентируются требования к реализации языка, но ... читаем между строк ... не сама реализация. Да и глупо это было бы регламентировать реализацию на стопицот осей.
                    Цитата JoeUser @
                    Вообще-то для меня будет откровением если ты приведешь материал из Стандарта, где вообще упоминается M$ Windows, применительно к любому разделу/теме.

                    Речь не о упоминании Windows в стандарте С++. Ты меня не так понял видимо.

                    Ок, я повторюсь и перефразирую:
                    Перед тобой стоит задача распаралелить алгоритм, при этом как можно лучше его оптимизировать. Что ты выберешь - std::mutex или std::recursive_mutex - для защиты общих ресурсов, и почему?

                    Добавлено
                    Цитата Wound @
                    Что ты выберешь - std::mutex или std::recursive_mutex - для защиты общих ресурсов, и почему?

                    А если нужно защитить ресурс - передаваемый между процессами - какой механизм ты выберешь и почему?
                    Сообщение отредактировано: Wound -
                      Цитата Wound @
                      Вопрос - он реализован как критическая секция или нет?

                      Wound, ты уже третий раз повторяешься. Смотри исходники!
                      К примеру реализация С++ в тулчейне MinGW-w64 имеет две варианта (реализации) с моделями win-theads и posix-threads. И, скорее всего, мьютексы там будут реализованы по разному. Как именно, в исходниках быть должно. Я не смарел - не знаю.
                        Цитата JoeUser @
                        Wound, ты уже третий раз повторяешься. Смотри исходники!

                        Какие исходники? Те что ты привел по ссылке или те что у меня в студии ?

                        Цитата JoeUser @
                        К примеру реализация С++ в тулчейне MinGW-w64 имеет две варианта (реализации) с моделями win-theads и posix-threads. И, скорее всего, мьютексы там будут реализованы по разному. Как именно, в исходниках быть должно. Я не смарел - не знаю.

                        Ты понимаешь чем отличается виндовый мьютекс от критической секции? Ты понимаешь что акроним - Мьютекс, а это именно уже акроним в Windows системе - означает, это очень медленная операция?
                        Я не знаю понимаешь ли ты это отличия или нет. Фишка даже не в этом, фишка в другом - как мне писать программу, многопоточную - для разных систем - допустим Windows и Linux ? Мне достаточно использовать STL мьютекс или мне так же, как и прежде придется писать код под разные платформы?

                        Добавлено
                        Просто я ожидаю от STL, что получу что то универсальное для любой ОС(ну как Java или там C# -им плевать где запустился - всегда действуют одни и те же правила, ну это в среднем.). В итоге пока не ясно, но по предварительным рассуждениям - я получаю что то узконаправленное под конкретную задачу, привязанную к Linux, потому что Windows Mutex не поддерживаются? А если поддерживаются, то под Винду я получу проседание производительности на порядок?
                        Сообщение отредактировано: Wound -
                          Цитата Wound @
                          Какие исходники? Те что ты привел по ссылке или те что у меня в студии ?

                          Как раз об этом и говорил - о "реализации" :lol: Реализация std::recursive_mutex и std::mutex в твоей студии, в migw32, в clang'е - может отличаться реализацией как с использованием мьютексов винды, так и с использованием критических секций. И это предстоит тебе найти в исходниках. Исходники STL студии ты вряд ли найдешь, а для mingw-w64 запросто.

                          Но, коль ты упомянул:

                          Цитата Wound @
                          ИМХО без этого знания - я не могу писать кросплатформенное приложение и опираться на стандартную библиотеку STL.


                          Но ведь ты желаешь лучшей производительности? Тогда тебе придется выяснить работу std::recursive_mutex и std::mutex и для других осей. Так вот, к примеру, для FreeBSD и Mac OSX крайне желательно использовать clang'овскую реализацию STL, и ее уже исследовать. Бенчмарки там какие-то по этому вопросу пролетали.

                          Добавлено
                          Цитата Wound @
                          А если поддерживаются, то под Винду я получу проседание производительности на порядок?

                          Вижу два выхода ... или все ж исследовать исходники (или тупо написать наборы тестов), или использовать PIMPL и для венды везде где можно использовать критические секции.

                          Лан, Киля, народ подтянется - возможно кто-то это уже разбирал. Пошел я в анабиоз :)
                            Цитата JoeUser @
                            Как раз об этом и говорил - о "реализации" :lol: Реализация std::recursive_mutex и std::mutex в твоей студии, в migw32, в clang'е - может отличаться реализацией как с использованием мьютексов винды, так и с использованием критических секций. И это предстоит тебе найти в исходниках. Исходники STL студии ты вряд ли найдешь, а для mingw-w64 запросто.

                            Вот видишь, и ты, пусть даже бессознательно, указал на некоторые проблемы. В частности - в разных компиляторах - слово мьютекс - может по разному интерпретироваться, и по разному реализовываться.

                            Цитата JoeUser @
                            Но ведь ты желаешь лучшей производительности?

                            Да!

                            Цитата JoeUser @
                            Тогда тебе придется выяснить работу std::recursive_mutex и std::mutex и для других осей.

                            Почему осей? Почему не компиляторов? Какие гарантии что в Майкрософт - std::mutex реализовали через критические секции? Я именно об этом и спрашиваю как бы :-?

                            Цитата JoeUser @
                            Так вот, к примеру, для FreeBSD и Mac OSX крайне желательно использовать clang'овскую реализацию STL, и ее уже исследовать. Бенчмарки там какие-то по этому вопросу пролетали.

                            Это твое ИМХО, потому что бенчмарки пролетали? Или почему? А в чем отличие от стандарта С++?

                            Цитата JoeUser @
                            Вижу два выхода ... или все ж исследовать исходники (или тупо написать наборы тестов), или использовать PIMPL и для венды везде где можно использовать критические секции.

                            То есть STL не гарантирует что std::mutex - поможет в лочке ресурсов между процессами? А значит можно сделать вывод что std::mutex реализован через Критические секции?

                            Цитата JoeUser @
                            Лан, Киля, народ подтянется - возможно кто-то это уже разбирал. Пошел я в анабиоз :)

                            Да, давай, приятно было пообщаться ))
                              JoeUser отчасти прав. Стандарт регламентирует поведение, но не реализацию. Так что MS может сотворить, что ей заблагорассудится, лишь бы поведение соответствовало. Т.к. и мьютексы, и критические секции в WinAPI обладают одинаковым поведением, заюзаны могут быть как те, так и другие.
                              Теперь анализ постановки задачи. Лично я не думаю, что MS будет использовать мьютексы просто так, потому что захотелось почаще перекидывать программу в ядро. Так что если нет особых причин, скорее всего используются критические секции. Мьютексы от критических секций по поведению отличаются лишь тем, что могут шариться между процессами. Других отличий нет. И тут вот засада: Стандарт не описывает взаимодейсвтие разных программ, он описывает поведение некой виртуальной исполнительной среды C++ в части подготовки и исполнения одной программы. Поэтому в нём не предусмотрено ничего для описания взаимодействия разных программ, даже если они все написаны на C++.
                              Резюме: почти наверняка используются критические секции. У MS не было причин выбирать более медленные мьютексы, т.к. Стандарт не способен задействовать их преимущества.
                                JoeUser, вот смотри - есть у тебя std::string и допустим std::endl, ты пишешь кросплатформеную программу, и нужно что то вывести куда то там в файл или в поток - не важно, ты пишешь:
                                ExpandedWrap disabled
                                  std::cout << "Message" << std::endl

                                И пишешь ты это например на определенном компиляторе, допустим шланг там или МСВС, или ГЦЦ, не важно, но ведь ты ожидаешь что везде и всюду, на любой ОС - ты получишь сообщение "Меssage". Потоки были стандартизированы еще в С++11, ЕМНИП. Отсюда возникает вопрос в использовании - раз они стандартные, значит и к ним какие то требования должны идти, вот я и хочу услышать - что такое std::mutex и чем он принципиально отличается от std::recursive_mutex. Иначе тогда смысл теряется в кроссплатформенном программировании. Я могу юзнуть std::mutex, под Линух, и все тесты написать и все будет в Шоколаде, но под винду моя программа не будет работать вообще, хотя будет написана по последнему слову стандарта.

                                Добавлено
                                Цитата Qraizer @
                                Резюме: почти наверняка используются критические секции. У MS не было причин выбирать более медленные мьютексы, т.к. Стандарт не способен задействовать их преимущества.

                                То есть std::mutex - это почти наверняка скорее всего критическая секция? Я правильно понимаю? То есть если я использую std::mutex, то в принципе могу не волноваться о том, что производительность просядет за счет переключения в kernel mode, по крайней мере в Windows? Или лучше всегда юзать std::recursive_mutex, и не париться?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0589 ]   [ 17 queries used ]   [ Generated: 28.03.24, 23:30 GMT ]