LINUX.ORG.RU

Почему программы зависают?

 


0

2

Пишут что в теории это как бы невозможно:

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

http://ermak.cs.nstu.ru/mos1/chap_3_3.php

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

Как же это возможно, ведь нас должна от этого оберегать «священная» вытесняющая многозадачность?


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

Примеры? Ты наверное путаешь с исчерпанием памяти, тогда ядро медленно ворочается и не может убить процесс, съевший всю память. При чём здесь вытесняющая многозадачность?

ox55ff ★★★★★
()

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

static_lab ★★★★★
()

Например потому что GUI обычно основаны на кооперативной колбековой многозадачности. Там есть главный цикл который обрабатывает очередь сообщений и вызывает соответствующие колбеки для обработки каждого сообщения. Если какой-то колбек завис то всё приложение зависнет.

Есть ещё зависания из-за ошибок использования примитивов синхронизации (мьютексы, семафоры и т.п.) и дедлоков.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)

Почему программы зависают?

у программистов лапки.

P.S. после очередного обновления Firefox на телефоне до версии 99, раз в сутки браузер тупо виснет насмерть, приходится прибивать руками.

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

тьфу.

annerleen ★★★★☆
()
Последнее исправление: annerleen (всего исправлений: 1)
Ответ на: комментарий от X512

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

это однозадачная event-driven архитектура. при появлении события система просыпается, обрабатывает его (выбором обработчика) в главном треде и засыпает. «обработчик кнопки» не является задачей!

alysnix ★★★
()
Ответ на: комментарий от static_lab

это теоретически невозможно в общем случае — Проблема остановки

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

no2700
() автор топика
Ответ на: комментарий от X512

Даже если внутри программы кооперативная, снаружи планировщик все равно ее переключает, разве нет? самому GUY разве не выделяется процессорное время? У него безлимит?

no2700
() автор топика
Ответ на: комментарий от alysnix

«обработчик кнопки» не является задачей!

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

X512 ★★★★★
()
Ответ на: комментарий от no2700

Даже если внутри программы кооперативная, снаружи планировщик все равно ее переключает, разве нет?

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

X512 ★★★★★
()
Ответ на: комментарий от no2700

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

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от alysnix

почему это не является? Все тоже самое.

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

no2700
() автор топика
Ответ на: комментарий от no2700

Эффект глобального зависания может создавать например ожидание общего для многих программ события, например открытие и чтение файлов с одной и той же ФС.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)

Напоминаю, что «центральный планирующий механизм» - это тоже программа, и ее тоже писали программисты. А у них, как уже верно заметили в треде, лапки.

thesis ★★★★★
()
Ответ на: комментарий от X512

Это вот как раз один из явных недостатков вытесняющей многозадачности, потому что в кооперативной один процесс всегда имеет эксклюзивный доступ ко всей памяти

no2700
() автор топика
Ответ на: комментарий от X512

Но вообще то они заявляют что проблема доступа давно решена.

Я считаю что решить ее проще всего инкапсуляцией памяти в обьект с очередью, это как бы самоочевидное решение

no2700
() автор топика
Ответ на: комментарий от X512

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

попробуйте компилятор gcc хотя бы мысленно разбить на хуки.

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

alysnix ★★★
()
Ответ на: комментарий от no2700

Это вот как раз один из явных недостатков вытесняющей многозадачности, потому что в кооперативной один процесс всегда имеет эксклюзивный доступ ко всей памяти

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

напомним что в вытесняющей многозадачности шедулер при появлении ивента высокого приоритета,и пробуждении треда высокого приоритета СРАЗУ переключает на него исполнение. такой скорости реакции в кооперативной просто не достичь… ну если только не ставить yield() после каждой строчки кода.

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

alysnix ★★★
()
Ответ на: комментарий от X512

У Оберона компилятор быстрый, так что компиляция одного исходника – одна задача.

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

ваши задачки - чисто модельные. частные случаи хорошей жизни.

alysnix ★★★
()
Ответ на: комментарий от alysnix

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

X512 ★★★★★
()
Ответ на: комментарий от alysnix

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

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)

Почему программы зависают?

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

BLOBster ★★★
()
Ответ на: комментарий от ox55ff

Но это фича появилась только в 2006 году, и она не контролирует все процессы, правильно?

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

no2700
() автор топика
Ответ на: комментарий от no2700

Лимиты (ulimit) были ещё раньше.

Распределение памяти работает в режиме overcommit. Т.е. выделение физической памяти происходи не в момент malloc/new, а при попытке доступа к этой памяти. malloc/new дают только виртуальную память и могут дать больше чем есть в системе физической.

ox55ff ★★★★★
()
Ответ на: комментарий от no2700

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

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

goingUp ★★★★★
()
Ответ на: комментарий от ox55ff

Т.е. выделение физической памяти происходи не в момент malloc/new, а при попытке доступа к этой памяти

а то, что при выделении блока менеджером кучи, туда НЕМЕДЛЯ прописывается его размер(вы как будете его деаллокировать по указателю?) и прочие штучки(зависит от реализации менеджера) - пофиг что ли? карочи. доступ к этой памяти идет уже внутри malloc, тогда причем тут некий overcommit?

alysnix ★★★
()

Вообще то процессы вытесняются с помощью прерываний таймера процессора или системными вызовами (которые тоже прерывания). Процессы всегда вытесняются в linux, это закон!

realbarmaley ★★
()
Ответ на: комментарий от X512

Железки как раз риалтайм обычно, не? Потерять какое-то внешнее сообщение/данные или даже обработать их с задержкой там нельзя.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

Железки как раз риалтайм обычно, не? Потерять какое-то внешнее сообщение/данные или даже обработать их с задержкой там нельзя.

можно, конечно! Называется «под нагрузкой выше пиковой»

seiken ★★★★★
()
Ответ на: комментарий от seiken

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 2)