Стан гонитви

Стан гонитви (англ. race condition, race hazard) — помилкова ситуація під час виконання програми, в якій робота системи чи результат операції залежить від того, в якій послідовності, або ж з якою тривалістю виконуються окремі інструкції коду.

Стан гонитви є специфічною помилкою проектування системи, трапляється в багатопотокових і розподілених програмах. Проявляється неконтрольовано у випадкові моменти часу і досить часто симптоми стану гонитви зникають, якщо спробувати її злокалізувати.

Свою назву отримала від схожої помилки проектування електронних схем та поняття «перегонів сигналів».

Програмне забезпечення

Стани гонитви проявляються в застосунках, де окремі процеси або потоки виконання залежать від одного спільного стану. Дії над спільним станом є критичними секціями, що мають бути несумісними. Невдача в цьому призводить до можливості пошкодження спільного стану.

Стани гонитви горезвісно складні для відтворення і зневадження, бо кінцевий результат не є детерміністичним і дуже залежить від відносного перебігу виконування процесів, що взаємодіють. Проблеми, що зустрічаються в готових системах можуть зникнути при запуску в режимі зневадження, коли відбувається додаткове журналювання і перевіряння або коли приєднується зневаджувач. Часто такий стан називають гайзенбагом. Дуже радять уникати станів гонитви через уважне розробляння програми, а не через виправляння проблеми потім.

Приклад

Як простий приклад розглянемо два потоки, що хочуть збільшити на одиницю глобальну цілочисельну змінну. В ідеалі, потрібна така послідовність операцій:

Потік 1Потік 2Ціле
0
прочитати0
збільшити0
записати1
прочитати1
збільшити1
записати2

так ми отримаємо 2, як і очікували. Однак, якщо два потоки запустяться одночасно без блокування або синхронізації:

Потік 1Потік 2Ціле
0
прочитати0
прочитати0
збільшити0
збільшити0
записати1
записати1

Кінцеве значення 1, а не 2. Це станеться через те, що операції збільшення виконуються сумісно. несумісні дії — це такі, які не можна перервати під час доступу до деяких ресурсів, таких як пам'ять. У першому випадку, Потік 1 не переривали під час доступу до змінної, отже його операція була несумісною.

C++

Стандарт С++11 у параграфі 1.10 визначає стан гонитви так:

  • Обчислення двох виразів конфліктує якщо один з виразів змінює ділянку пам'яті, а другий читає або також змінює ту саму ділянку пам'яті.
  • Перебіг програми має стан гонитви, якщо він містить в різних потоках дві дії, що конфліктують, щонайменше одна з яких не атомарна і жодна не відбувається перед іншою.

Див. також

Посилання


This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.