Вопрос:

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

multithreading concurrency locking deadlock

97729 просмотра

16 ответа

10218 Репутация автора

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

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

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

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

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

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

Автор: bmurphy1976 Источник Размещён: 29.08.2008 03:56

Ответы (16)


184 плюса

99143 Репутация автора

Решение

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

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

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

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

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

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

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

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

Автор: Keith Размещён: 29.08.2008 03:58

2 плюса

10110 Репутация автора

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

Автор: Joseph Sturtevant Размещён: 29.08.2008 03:59

7 плюса

23069 Репутация автора

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

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

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

Thread 1               Thread 2

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

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

Автор: 17 of 26 Размещён: 29.08.2008 04:04

34 плюса

15835 Репутация автора

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

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

  • избегать замков (если это возможно),
  • избегать использования более одного замка
  • всегда берите замки в одном и том же порядке.
Автор: Mats Fredriksson Размещён: 29.08.2008 04:19

0 плюса

8143 Репутация автора

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

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

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

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

Автор: mweerden Размещён: 02.09.2008 08:42

4 плюса

27779 Репутация автора

Вы можете взглянуть на эту замечательную статью в разделе Deadlock . Это в 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
}
Автор: onmyway133 Размещён: 25.09.2013 06:45

-2 плюса

3314 Репутация автора

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

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

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

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

  • Удерживать замок как можно быстрее.

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

Автор: Marcus Thornton Размещён: 08.11.2013 02:54

2 плюса

268943 Репутация автора

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

Автор: user207421 Размещён: 03.02.2014 05:38

0 плюса

1 Репутация автора

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

Автор: puja bharti Размещён: 19.04.2015 01:57

18 плюса

3483 Репутация автора

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

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

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

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

Состояние или ситуация тупика

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

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

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

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

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

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

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

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

Автор: Varun Размещён: 07.05.2015 12:47

4 плюса

4714 Репутация автора

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

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

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

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

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

Автор: Rohit Singh Размещён: 04.02.2016 07:29

116 плюса

7052 Репутация автора

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

Криминальная и полицейская сцена

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

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

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

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

Автор: Levent Divilioglu Размещён: 25.02.2016 11:35

0 плюса

31 Репутация автора

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

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

Спасибо,

Автор: Sapna Размещён: 15.04.2017 01:52

0 плюса

1008 Репутация автора

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

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

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

jcmd $PID Thread.print

ссылка : гиксфоргекс

Автор: Arun Raaj Размещён: 24.04.2018 11:11

1 плюс

4228 Репутация автора

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

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

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

Автор: Vivek Pratap Singh Размещён: 22.08.2018 06:54

0 плюса

137 Репутация автора

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

Автор: Raghav Navada Размещён: 28.08.2019 10:44
32x32