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



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



мои вопросы к сообществу:




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


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


  3. вы справляетесь с ними?


  4. и, наконец, как вы предотвращаете их появление?


1360   16  

16 ответов:

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

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

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

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

ресурса а и ресурса Б используются и процесс X процесс y

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

лучший способ избежать взаимоблокировок-это избежать пересечения процессов таким образом. Уменьшить нужно зафиксировать как можно больше.

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

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

Криминальная И Полицейская Сцена

enter image description here

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

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

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

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

способы избежать возникновения тупиков:

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

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

взаимоблокировка происходит, когда поток ждет чего-то, что никогда не происходит.

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

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

Thread 1               Thread 2

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

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

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

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

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
}

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

первоначально ОС назначает R1 для обработки P1 и R2 для обработки P2. Поскольку оба процесса выполняются одновременно, они могут начать выполнять свой код, но проблема возникает, когда процесс попадает в критический раздел. Таким образом, процесс R1 будет ждать процесса P2, чтобы релиз R2 и наоборот... Поэтому они будут ждать вечно (условие тупика).

небольшая аналогия...

твоя мать (ОС),
Ты (P1),
Твой брат (P2),
Яблоко(Р1),
Нож(Р2),
критическая секция (разрезание яблока ножом).

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

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

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

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

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

condition условие удержания и ожидания: процессы, в настоящее время удерживающие ресурсы, предоставленные ранее, могут запрашивать новые ресурсы.

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

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

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

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

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

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

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

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

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

спасибо,

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

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

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

jcmd $PID Thread.print

ссылка : geeksforgeeks

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

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.главное, он проверяет, является ли класс ленивым был инициализирован и начинает инициализировать класс. Этот основной поток теперь инициализируется в false , создает и запускает в фоновом режиме поток, метод run которого устанавливает инициализированное значение true, и ожидает завершения фонового потока.

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

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

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

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

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

  • удерживая замок как можно меньше времени.

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

Comments

    Ничего не найдено.