Что такое тупик?

При написании многопоточных приложений одной из наиболее распространенных проблем является взаимоблокировка.

Мои вопросы для сообщества:

  • Что такое тупик?

  • Как вы их обнаруживаете?

  • Вы справляетесь с ними?

  • И, наконец, как вы их предотвращаете?

Ответ 1

A блокировка возникает, когда несколько процессов пытаются получить доступ к одному и тому же ресурсу в одно и то же время.

Один процесс проигрывает и должен ждать завершения другого.

A тупик возникает, когда процесс ожидания все еще удерживается на другом ресурсе, который требуется прежде, чем он сможет завершить.

Итак, пример:

Ресурс A и ресурс B используются процессом X и обрабатываются Y

  • X начинает использовать A.
  • X и Y попытайтесь начать использовать B
  • Y 'выигрывает' и сначала получает B
  • Теперь Y нужно использовать A
  • A заблокирован X, который ждет Y

Лучший способ избежать взаимоблокировок - избегать переходов процессов таким образом. Уменьшите необходимость блокировки всего, насколько сможете.

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

Ответ 2

Позвольте мне объяснить реальный мир (на самом деле не реальный) пример ситуации тупика из фильмов о преступлениях. Представьте, что преступник держит заложника, и против этого полицейский также имеет заложника, который является другом преступника. В этом случае преступник не собирается отпускать заложника, если полицейский не позволит своему другу отпустить. Также полицейский не собирается отпускать друга преступника, если преступник не освободит заложника. Это бесконечная ненадежная ситуация, потому что обе стороны настаивают на первом шаге друг от друга.

Уголовная и полицейская сцена

введите описание изображения здесь

Так просто, когда двум потокам нужны два разных ресурса, и каждый из них имеет блокировку ресурса, который нужен другой, это тупик.

Еще одно объяснение тупика: Разбитые сердца

Вы встречаетесь с девушкой, и на следующий день после спора обе стороны сбиты друг с другом и ждут вызова I-am-sorry-and-I-missed-you, В этой ситуации обе стороны хотят общаться друг с другом тогда и только тогда, когда один из них получает вызов I-am-sorry от другого. Поскольку ни один из них не собирается начинать общение и ждать в пассивном состоянии, оба будут ждать другого, чтобы начать общение, которое заканчивается в ситуации взаимоблокировки.

Ответ 3

Тупики будут возникать только тогда, когда у вас есть два или более замка, которые могут быть приобретены одновременно, и они схвачены в другом порядке.

Способы избежать взаимоблокировок:

  • избегайте блокировок (если возможно),
  • избегать использования нескольких блокировок
  • всегда берет блокировки в том же порядке.

Ответ 4

Чтобы определить тупик, сначала я бы определил процесс.

Процесс :. Как мы знаем, процесс является не чем иным, как program.

Ресурс : Для выполнения процесса программы требуются некоторые ресурсы. Категории ресурсов могут включать память, принтеры, процессоры, открытые файлы, ленточные накопители, CD-ROM и т.д.

Тупик : Тупик - это ситуация или условие, когда два или несколько процессов содержат некоторые ресурсы и пытаются получить дополнительные ресурсы, и они не могут освобождать ресурсы до тех пор, пока они заканчивают выполнение.

Состояние или ситуация взаимоблокировки

enter image description here

На приведенной выше диаграмме есть два процесса P1 и p2, и есть два ресурса R1 и R2.

Ресурс R1 выделяется для процесса P1, а ресурс R2 выделяется для процесса p2. Для выполнения процесса P1 требуется ресурс R2, поэтому P1 запрос R2, но R2 уже выделено P2.

Таким же образом для процесса выполнения P2 требуется выполнить R1, но R1 уже выделен P1 > .

оба процесса не могут освободить свой ресурс до тех пор, пока они не завершат выполнение. Так что оба ждут других ресурсов, и они будут ждать вечно. Итак, это условие DEADLOCK.

Для того, чтобы возникла тупиковая ситуация, должны быть выполнены четыре условия.

  • Взаимное исключение. Каждый ресурс либо в настоящее время распределяется только на один процесс, либо доступен. (Два процесса не могут одновременно контролировать один и тот же ресурс или быть в их критическом раздел).
  • Удержание и ожидание - процессы, в которых в настоящее время хранятся ресурсы, могут запрашивать новые ресурсы.
  • Без преемственности. Когда процесс содержит ресурс, он не может быть удален другим процессом или ядром.
  • Циклическое ожидание. Каждый процесс ожидает получения ресурса, который удерживается другим процессом.

и все эти условия выполняются на диаграмме выше.

Ответ 5

Тупик происходит, когда поток ждет чего-то, что никогда не происходит.

Обычно это происходит, когда поток ожидает мьютекс или семафор, который никогда не был выпущен предыдущим владельцем.

Это также часто случается, когда у вас есть ситуация, связанная с двумя потоками и двумя блокировками вроде этого:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

Обычно вы обнаруживаете их, потому что все, чего вы ожидаете, никогда не произойдет, или приложение полностью зависает.

Ответ 6

Вы можете взглянуть на замечательные статьи в разделе Тупик. Это в С#, но идея по-прежнему остается той же для другой платформы. Я цитирую здесь для удобства чтения

Тупик происходит, когда два потока ожидают ресурс, удерживаемый другой, поэтому и не может продолжаться. Самый простой способ проиллюстрировать это с двумя замками:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}

Ответ 7

Deadlock является распространенной проблемой в многопроцессорных/многопрограммных задачах в ОС. Скажем, есть два процесса P1, P2 и два глобально совместно используемых ресурса R1, R2, и в критическом разделе должны быть доступны оба ресурса

Первоначально ОС назначает R1 для обработки P1 и R2 для обработки P2. Поскольку оба процесса работают одновременно, они могут начать выполнять свой код, но ПРОБЛЕМА возникает, когда процесс попадает в критическую секцию. Так что процесс R1 будет ждать, пока процесс P2 выпустит R2, и наоборот... Так что они будут ждать вечно (СОСТОЯНИЕ ЗАГЛУШКИ).

Небольшая АНАЛОГИЯ...

Твоя Мать (О.С.),
Вы (P1),
Твой брат (P2),
Apple, (R1),
Нож (R2)
критическая секция (резка яблока ножом).

Сначала твоя мать дает тебе яблоко и нож твоему брату.
Оба счастливы и играют (исполняют свои коды).
Любой из вас хочет в какой-то момент порезать яблоко (критический раздел).
Вы не хотите давать яблоко своему брату.
Твой брат не хочет давать тебе нож.
Так что вы оба будете ждать очень долго очень долго :)

Ответ 8

Тупик возникает, когда два потока захватывают блокировки, которые не позволяют любому из них развиваться. Лучшим способом избежать их является тщательное развитие. Многие встроенные системы защищают их от использования сторожевого таймера (таймер, который сбрасывает систему, если она зависает в течение определенного периода времени).

Ответ 9

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

Ответ 10

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

 Условие взаимного исключения: каждый ресурс либо в настоящее время назначается точно одному процессу, либо доступен.

 Условие ожидания и ожидания. Процессы, в которых в настоящее время хранятся предоставленные ранее ресурсы, могут запрашивать новые ресурсы.

 Отсутствие условия преимущественного использования: ранее предоставленные ресурсы не могут быть принудительно удалены из процесса. Они должны быть явно освобождены в процессе их проведения.

 Условие циклического ожидания: должна существовать круговая цепочка из двух или более процессов, каждая из которых ждет ресурса, удерживаемого следующим членом цепочки. В общем, для борьбы с взаимоблокировками используются четыре стратегии. Они есть:  Просто игнорируйте проблему в целом. Может быть, если вы проигнорируете это, это будет игнорировать вас.  Обнаружение и восстановление: позволяют создавать взаимоблокировки, обнаруживать их и принимать меры.  Динамическое предотвращение путем тщательного распределения ресурсов.  Предотвращение: путем структурного отрицания одного из четырех условий, необходимых для тупиковый.

Ответ 11

Классическая и очень простая программа для понимания ситуации тупика: -

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

Когда основной поток вызывает Lazy.main, он проверяет, является ли класс Lazy был инициализирован и начинает инициализировать класс. основной поток теперь устанавливает инициализированное значение false, создает и запускает фон поток, метод запуска которого устанавливает значение initialized в значение true и ожидает завершения фонового потока.

На этот раз класс в настоящее время инициализируется другим потоком. В этих условиях текущий поток, который является фоновым потоком, ожидает объекта Class до завершения инициализации. К сожалению, поток который выполняет инициализацию, основной поток ожидает фон нить для завершения. Поскольку два потока теперь ждут друг друга, Программа заблокирована.

Ответ 12

Тупик - это состояние системы, в которой ни один процесс/поток не способен выполнять действие. Как упоминалось другими, тупик обычно является результатом ситуации, когда каждый процесс/поток хочет получить блокировку ресурса, который уже заблокирован другим (или даже тем же) процессом/потоком.

Существуют различные методы, чтобы найти их и избежать их. Один очень много думает и/или пытается много чего. Однако работа с parallelism, как известно, сложна, и большинство (если не все) людей не смогут полностью избежать проблем.

Некоторые более формальные методы могут быть полезны, если вы серьезно относитесь к этим вопросам. Самый практичный метод, о котором я знаю, - использовать теоретический подход к процессу. Здесь вы моделируете свою систему на каком-либо языке процесса (например, CCS, CSP, ACP, mCRL2, LOTOS) и используете доступные инструменты для проверки (model-) для взаимоблокировок (и, возможно, некоторых других свойств). Примерами используемого набора инструментов являются FDR, mCRL2, CADP и Uppaal. Некоторые храбрые души могут даже доказать, что их системы взаимоблокированы, используя чисто символические методы (доказательство теоремы, поиск Овицки-Гриса).

Однако эти формальные методы обычно требуют определенных усилий (например, изучение основ теории процессов). Но я предполагаю, что это просто следствие того, что эти проблемы сложны.

Ответ 13

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

Ответ 14

Выше некоторые объяснения хороши. Надеюсь, это также может быть полезно: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

В базе данных, когда сеанс (например, ora) хочет ресурс, хранящийся в другом сеансе (например, данные), но этот сеанс (данные) также требует ресурса, который удерживается первым сеансом (ora). Также может участвовать более двух сеансов, но идея будет одинаковой. На самом деле, Deadlock блокируют некоторые транзакции от продолжения работы. Например: Предположим, ORA-DATA содержит блокировку A и блокирует запрос B И SKU удерживает блокировку B и запрашивает блокировку A.

Спасибо,

Ответ 15

Взаимная блокировка возникает, когда поток ожидает завершения другого потока, и наоборот.

Как избежать?
               - Избегайте вложенных замков
 - Избегайте ненужных замков
 - Использовать нить join()

Как вы это обнаружили?
запустите эту команду в cmd:

jcmd $PID Thread.print

ссылка: geeksforgeeks

Ответ 16

Замки не просто возникают с замками, хотя это самая частая причина. В C++ вы можете создать взаимоблокировку с двумя потоками без блокировок, просто вызвав каждый поток вызовом join() для объекта std::thread для другого.

Ответ 17

Мьютекс - это блокировка, обеспечивающая защищенный доступ к общим ресурсам. Под Linux тип данных mutex потока - pthread_mutex_t. Перед использованием инициализируйте его.

Для доступа к общим ресурсам вам необходимо заблокировать мьютексы. Если мьютекс уже заблокирован, вызов блокирует поток до тех пор, пока мьютекс не будет разблокирован. По завершении посещения разделяемых ресурсов вам необходимо разблокировать их.

В целом, есть несколько неписаных основных принципов:

  • Получите блокировку перед использованием общих ресурсов.

  • Удерживая замок как можно короче.

  • Отпустите блокировку, если поток возвращает ошибку.