Скажем, у меня многопоточное приложение, и я запускаю его с теми же входами. Достаточно ли для каждой загрузки и хранилища регистрировать записи для записи и записи данных? Я имею в виду из зарегистрированных загружаемых и хранимых адресов, если мы можем видеть, какой поток выполнял загрузку и какой поток выполнял это хранилище, мы можем обнаружить расы записи записи и записи-записи, заметив перекрывающиеся адреса. Или я чего-то не хватает?Достаточно ли этого, чтобы обнаружить условия гонки?
ответ
Или я что-то упускаю?
Вы: : отсутствует. Как сказал Пубби, если вы видите прочитанное, то напишите в T1, а затем прочитайте, затем напишите в T2, вы не можете сказать ничего об отсутствии рас. Вам нужно знать о блокировках.
Возможно, вы захотите использовать такой инструмент, как Google ThreadSanitizer.
Update:
Но будет ли мой подход охватывает все расы или, по крайней мере, некоторые из рас?
Ваши комментарии здесь и по другим ответам показывают, что вы не понимаете, что такое гонка.
Ваш подход май выставить рас, да. Гарантируется, что не покрывает большинство из них (что сделает упражнение бесполезным).
Наиболее очевидная вещь, которую вы узнаете, состоит в том, что существует несколько потоков, использующих одну и ту же память. Это не обязательно плохо само по себе.
Хорошее использование будет включать защиту с помощью семафоров, атомарного доступа и механизмов типа RCU или двойной буферизации.
Плохих применения будет включать в себя условие расы, истинное и ложный обмен:
- условие гонки в основном стволовые от упорядочения вопросов - если какая-то задача пишет что-то в конце его исполнения, тогда как задача B необходимо это значение в его начало, вы должны убедиться, что чтение B происходит только после завершения A. Хорошим решением для этого являются семафоры, сигналы или подобное. Или, конечно, запустите его в том же потоке.
- Истинное совместное использование означает, что два или более ядра активно считывают и записывают один и тот же адрес памяти. Это замедляет работу процессора, так как ему постоянно приходится отправлять какие-либо изменения в кеши других ядер (и, конечно, память). Ваш подход мог поймать это, но, вероятно, не выделить его.
- Ложное совместное использование еще более сложное, чем реальное совместное использование: кеши процессора не работают ни на одном байте, а на «линиях кеша», которые содержат более одного значения. Если ядро A продолжает забивать байт 0 строки, тогда как ядро B продолжает записывать в байт 4, обновление кеша все равно остановит весь процессор.
Я уже знаю эти вещи. Это не отвечает на мой вопрос. – pythonic
Вот простой пример из Википедии, что я слегка модифицирована:
В качестве простого примера предположим, что два потока T1 и T2 каждый хочет для выполнения арифметических операций над значением глобальной целое на единицу. В идеальном случае должна выполняться следующая последовательность операций:
- Целое число i = 0; (Память)
- Т1 считывает значение I из памяти в register1: приращение 0
- Т1 значение I в register1: (содержание register1) + 1 = 1
- T1 сохраняет значение register1 в памяти: 1
- Т2 считывает значение I из памяти в Register2: 1
- Т2 умножает значение I в Register2: (содержание REGISTER2) * 2 = 2
- T2 сохраняет значение Register2 в памяти: 2
- Целое число i = 2; (память)
В случае, показанном выше, конечное значение i равно 2, как и ожидалось. Однако, если два потока выполняются одновременно без блокировки или синхронизации, результат операции может быть неправильным. Следующая альтернативная последовательность операций демонстрирует этот сценарий:
- Целое число i = 0; (Память)
- Т1 считывает значение I из памяти в register1: 0
- Т2 считывает значение I из памяти в Register2: приращение 0
- Т1 значение I в register1: (содержание register1) + 1 = 1
- Т2 умножает значение I в Register2: (содержание REGISTER2) * 2 = 0
- T1 сохраняет значение register1 в памяти: 1
- T2 сохраняет значение Register2 в памяти: 0
- Целое число i = 0; (Память)
Окончательное значение I равно 0 вместо ожидаемого результата 2. Это происходит потому, что инкремент операция второго случая не является взаимоисключающей . Взаимоисключающие операции - это те, которые не могут быть прерваны при доступе к некоторому ресурсу, например, к памяти . В первом случае T1 не прерывался при доступе к переменной i, поэтому ее операция была взаимно исключающей.
Все эти операции являются атомарными. Состояние гонки происходит потому, что этот определенный порядок не имеет той же семантики, что и первая. Как вы доказываете, что семантика не совпадает с первой? Ну, вы знаете, что они разные для этого случая, но вам нужно доказать каждый возможный порядок, чтобы определить, что у вас нет условий гонки. Это очень трудная задача и имеет огромную сложность (возможно, NP-hard или требует AI-complete) и, следовательно, не может быть надежно проверена.
Что произойдет, если определенный порядок не остановится? Как вы даже знаете, что это никогда не остановится в первую очередь? В основном вы решаете проблему остановки, которая является невыполнимой задачей.
Если вы говорите об использовании последовательных операций чтения или записи для определения расы, а затем наблюдать это:
- Integer я = 0; (Память)
- Т2 считывает значение I из памяти в Register2: 0
- Т2 умножает значение I в Register2: (содержание REGISTER2) * 2 = 0
- T2 сохраняет значение Register2 в памяти: 0
- Т1 считывает значение I из памяти в register1: приращение 0
- Т1 значение I в register1: (содержание register1) + 1 = 1
- T1 сохраняет значение register1 в памяти: 1
- Целое число i = 1; (Память)
Это имеет тот же шаблон для чтения/магазин как первый, но дает различные результаты.
Вы, кажется, не поняли мой вопрос. Здесь, если мы обрабатываем каждую загрузку и сохранение потоков 1 и 2, мы действительно увидим, что T2 и T1 записываются в одну и ту же переменную и таким образом обнаруживают нарушение записи/записи. Что в этом примере так сложно? Я тоже в порядке с ложными срабатываниями. У меня скорее есть ложный позитив, чем состояние гонки не обнаружено. Я не требую последовательной записи для чтения, я думаю, что чтение/запись, даже разделенные инструкциями, прекрасное, чтобы сказать о своем состоянии гонки. Мы можем игнорировать части кода внутри замков. Я думаю, что я говорю о жизнеспособном подходе. – pythonic
@ user1018562 Я не понимаю, как вы можете определить, какой код находится внутри замков (имейте в виду, что * код * не должен быть заблокирован, а вместо этого * данные *), поскольку это также требует решения проблемы с остановкой, и даже если вы возможно, все еще есть шансы на то, что произойдет гонка. – Pubby
- 1. Достаточно ли этого, или у меня есть условия гонки?
- 2. Достаточно ли этого, чтобы избежать xss?
- 3. MySQL гонки Условия
- 4. Условия гонки
- 5. Captcha: достаточно ли этого?
- 6. условия гонки в Джанго
- 7. JQuery вложенных $ .when, чтобы предотвратить условия гонки
- 8. Spring MVC - условия гонки?
- 9. Написано достаточно, чтобы обнаружить потерю соединения?
- 10. Условия гонки с OpenMP
- 11. Условия гонки баз данных
- 12. ActiveRecord условия find_or_initialize_by гонки
- 13. Разделяет ли ключевое слово «общий» условия гонки?
- 14. Условия гонки по директивам
- 15. babylonjs типография условия гонки?
- 16. Условия гонки в io.Pipe?
- 17. Условия гонки присвоения UVM
- 18. темы условия гонки
- 19. Являются ли условия гонки в EventMachine?
- 20. Могут ли условия гонки снизить производительность кода?
- 21. Android Аннотации @UiThread условия гонки?
- 22. Этого достаточно, чтобы защитить меня от XSS?
- 23. Как имитировать условия гонки конструктора?
- 24. Служба REST и условия гонки
- 25. Таймеры, файлы и условия гонки?
- 26. Как написать тесты, которые проверяют условия гонки?
- 27. этого условия достаточно для проверки переполнения при умножении
- 28. тест Установка для гонки условия
- 29. PHP - mysql_insert_id() и условия гонки?
- 30. MEAN JS DB гонки Условия
не будет автоматически искажать результаты, потому что это изменяет поведение во время работы ?! – 0xC0000022L
Если бы все было так просто, я уверен, что проблема была бы решена давно. Обнаружение - это одно; предотвращение - совсем другое. – duffymo
duffymo: Я просто говорю об обнаружении в этот момент. – pythonic