Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Один mutex на несколько функций - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Как вычислить суммы положительных элементов каждой строки матрицы? http://www.cyberforum.ru/cpp-beginners/thread1715359.html
пожалуйста,помогите написать программу. Даны целые числа n, m и матрица целых чисел A. Вычислить суммы положительных элементов каждой строки матрицы. Написать функции вычисления суммы положительных...
C++ Распечатать значения аргументов командной строки и параметров окружающей среды для текущего процесса Помогите. Написать программу, распечатывающую значения аргументов командной строки и параметров окружающей среды для текущего процесса. Если булет возможность с описанием всего, так как язык не знаю,... http://www.cyberforum.ru/cpp-beginners/thread1715356.html
Из одномерного массива чисел сформировать упорядоченный массив, удалив из него некоторые элементы C++
С произвольного одномерного массива вещественных чисел сформировать упорядоченный массив, в котором удалены максимальный и минимальной за значениями элементы.
C++ Ошибка инициализации классов
Доброго времени суток, Я в основном программирую на C#, но вот решил попробовать плюсы. И облом при первой же попытке, в шарпе при объявлении класса я пишу class MyClass1 { MyClass2 mc2 =...
C++ Сортировка одномерного массива разными методами http://www.cyberforum.ru/cpp-beginners/thread1715338.html
Нужно выполнить сортировку одномерного числового массива по следующим пунктам. Первую часть понимаю(а), дальше разобраться самому не получается. a) Сгенерировать одномерный массив из 60 элементов...
C++ Построение блок-схем алгоритмов средствами MS Visio 2010 и их реализация на языке C ++ Дано натуральное число n и действительные b1, b2, ..., b n. Вывести на экран по 3 числа в строка все парные элементы последовательности. подробнее

Показать сообщение отдельно
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3875 / 2133 / 548
Регистрация: 18.10.2014
Сообщений: 3,746
20.04.2016, 20:32
Цитата Сообщение от nmcf Посмотреть сообщение
Гонка - это когда мьютекса нет вообще и потоки мешают друг другу.
Ни в коем случае.

Race condition ("гонка") - это огромный класс семантических проблем, суть которых сводится к тому, что программа пытается завязываться на такие предположения о многопоточном поведении, которые на самом деле является неопределенными (unspecified или undefined). А именно, когда программа пытается делать предположения о существовании некоего детерминированного "порядка" или "скорости" выполнения потоков.

В этом множестве вариантов разнообразных гонок несинхронизированный/неатомарный доступ к кусочку данных - это лишь очень узенький и весьма нерепрезентативный частный пример возможной гонки. Это во-первых. Во-вторых, предположение о том, что "заоболачивание" доступа к данным в mutex как-то решает проблему гонки - наивное заблуждение. Это не говоря уже о том, что приемы синхронизации в многопоточном программировании далеко не сводятся к использованию "классических" примитивов, типа mutex.

Вот вам искусственный пример гонки, причем буквальной: пусть у меня есть глобальная переменная int i = 0 и несколько одинаковых потоков, которые, кроме прочего, делают ++i и запоминают результат. Пусть я запускаю эти потоки поочередно с задержкой Dt по времени между потоками. И я предполагаю, что те потоки, которые стартовали раньше, "доберутся" до ++i тоже раньше. Соответственно, я предполагаю, что первый запущенный поток получит из i значение - 1, второй - 2 и т.д. Пусть я в дальнейшем коде сильно завишу от выполнения этого предположения.

Вот это - яркий пример гонки. Мое предположение - грубейшим образом некорректно. То, что некий поток стартовал позже, никак не мешает ему обогнать более ранний поток в процессе выполнения. При этом заоболачивание доступа к ++i в mutex никак делу не поможет - выполнение моего предположения все равно не гарантируется и оно не будет выполняться. Вот это - классический race condition. Заоболочив доступ к ++i в mutex я лишь перенес точку финиша в этой гонке, но саму гонку и ее негативные последствия никак не устранил.

Нерадивый программист в такой ситуации может начать увеличивать величину задержки Dt, в надежде на то, что для какого-то значения Dt порядок прихода потоков на ++i, наконец, станет совпадать с порядком их запуска. Понятно, что это не более чем профанация.

В такой ситуации, если я действительно хочу, чтобы потоки выполняли ++i в некотором четко определенном мною порядке, я должен буду самостоятельно насильно ловить и задерживать "выбившиеся вперед" потоки. И делать это придется вручную.

Цитата Сообщение от nmcf Посмотреть сообщение
Если несколько потоков используют мьютекс для доступа к ресурсу, при этом порядок обращения к мьютексу и время удержания произвольные, то где гарантия, что один и тот же поток не будет неограниченно долго удерживать мьютекс просто освобождая и тут же захватывая его повторно, ведь очереди нет, и не гарантируется, что освобождение мьютекса одним поток обязательно активирует ожидающих?
Такая гарантия и есть, и нет.

Такая гарантия есть, потому что освобождение и последующий захват одного mutex потоком A - операция неатомарная. В традиционной реализации, если в этот момент какой-то другой поток B ожидал этого же mutex и был в этот момент готов к выполнению, этот поток B тут же захватит этот mutex еще в момент освобождения его потоком A. Как бы быстро A не попытался снова захватить mutex, он все равно "не успеет".

Такой гарантии нет например потому, что ожидающий поток B в момент освобождения mutex может оказаться не готов к выполнению. Например, ОС могла "на секундочку" захватить ресурсы потока B и переиспользовать их для решения каких-то своих внутренних задач (типа обслуживания прерывания неким внутренним системным потоком C). Поток B на это время будет "заморожен". Т.е. может получится так, что поток B "прохлопает" свою возможность захватить mutex, и поток A сможет успеть снова захватить его прямо под носом у потока B.

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

Но опять же, в недискриминирующем отношении ОС к потокам не содержится никаких гарантий порядка выполнения потоков. Если вам нужен порядок - огранизуйте его сами. И многопоточное программирование предполагает дизайн программы по принципу: если что-то очень маловероятно, но теоретически возможно, то оно рано или поздно произойдет.

Добавлено через 10 минут
Цитата Сообщение от Bushmeister Посмотреть сообщение
Ой, вот только не надо тут пальцы гнуть, если ещё кто-то не вникал в тему с мьютексами и знает их поверхностно, без практики. Похоже, придется напомнить, что это раздел для начинающих в C++. Для вас "странные вопросы" - абсолютно нормальные, логичные для тех, кто ещё не работал с этим серьезно и желает получить правильное решение, чтобы потом не наступать на грабли.
Перед вами никто не "гнет пальцы".

Когда некто в форуме "для начинающих математиков" задает вопрос типа "Решал уравнение x + 2 = 4. Получил ответ x=3, но что-то не сходится. Где ошибка?", то на такой вопрос можно дать два принципиально разных ответа. Первый ответ: "Правильное решение x=2. Свободен.". Второй ответ: "Покажи, как ты получил такой странный результат (а мы покажем тебе, где именно ты ошибся в процессе решения)". Я лично считаю, что в такой "странной" ситуации, как "решал x + 2 = 4, получил x=3" первый вариант ответа на самом деле бесполезен, а осмысленен именно и только второй вариант ответа.

Вот так же и здесь, когда я у вас спрашиваю, "откуда возник такой вопрос", цель этого - именно понять, какая цепочка умозаключений привела вас к "странному" выводу, что для трех функций необходимо три мьютекса, и затем уже искать ошибку в этой цепочке. Ни больше, ни меньше.
4
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru