LINUX.ORG.RU

Как ядро вызывает функцию из процесса?

 , , , ,


0

2

Хватит «перемещать темы в архив»! Неудобно же, плодятся десятки несвязанных тем, которые не найти потом.

Я бы хотел обсудить тему Работа с сигналами в Linux

Там есть ссылки, которые не работают, но сами статьи остались в Web Archive.

Автор пишет: «При доставке сигнала процессу ядро как можно скорее вызывает обработчик сигнала, прерывая работу процесса. По завершении работы обработчика выполнение процесса продолжается с того места, где он был прерван.»

Мне непонятно, как это происходит технически. Какая из многих нитей процесса останавливается, для того, чтобы вызывать сигнал? Верно ли, что регистры останавливаемой нити сохраняются в её личный стек? Или останавливаются все нити процесса, а запускается ещё одна, несвязанная?

★★★

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

как это происходит технически

Я б не стал полагаться на статью 12-летней давности. Особенно что касается технических деталей. Там всё уже 100 раз могло поменяться за это время.

no-such-file ★★★★★
()

Хватит «перемещать темы в архив»! Неудобно же, плодятся десятки несвязанных тем, которые не найти потом.

И не надо их искать, это не википедия, это просто история прошлых бесед. Есть вопрос - создавай новую.

firkax ★★★★★
()

Мне непонятно, как это происходит технически. Какая из многих нитей процесса останавливается, для того, чтобы вызывать сигнал?

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

Верно ли, что регистры останавливаемой нити сохраняются в её личный стек?

Да.

Или останавливаются все нити процесса, а запускается ещё одна, несвязанная?

Нет. Так только винда делает, но не останавливает ничего.

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

Сигналы в мультитред-процессах это особая тема.

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

А то «особая тема», «особая тема». Услышали где-то, повторяют как попугаи, и не способны объяснить в чём же дело конкретно.

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

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

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

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

Для всех остальных целей, где новичкам обычно хочется мультитред, если более удачные сингл-тред решения.

А особая она потому, что, в отличие от прямолинейной, стандартизированной и полностью предсказуемой синглтред-обработки, в мультитреде всё не так. Треды сами по себе по-разному реализованы в разных ОС (в линуксе это отдельные процессы с костыльной обёрткой в glibc, прячущей от приложения этот факт, в фрибсд это сущности внутри одного процесса, но тоже с обёрткой вокруг менявшихся от версии к версии ядерных механизмов). Уже этот факт исключает прозрачность в этой области.

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

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

в линуксе это отдельные процессы с костыльной обёрткой в glibc, прячущей от приложения этот факт

Если память общая, то какие же они отдельные? А если раздельная, то такой факт никой обёрткой не спрячешь.

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

При создании отдельного процесса можно выбрать общую память. Но это именно отдельные процессы, если вызвать из линуксового треда системный вызов _exit - то завершится только этот тред. Поэтому glibc-обёртка _exit() вызывает не _exit, а exit_group, которая находит все треды-процессы «процесса» и завершает их.

firkax ★★★★★
()

Какая из многих нитей процесса останавливается, для того, чтобы вызывать сигнал?

Скорее всего, первая которая сделает системный вызов и для которой этот сигнал не запрещён.

Мне непонятно, как это происходит технически.

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

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

Не верю. Думаю, что сигналы могут возникать и начать обрабатываться в любой момент, а не только при вызове системных функций. Иначе было бы нельзя прервать например компиляцию по Ctrl-C в консоли. Компиляция очень много ворочает памятью и мало обращается к системным функциям (считать исходный файл и записать результат компиляции).

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

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

xaizek ★★★★★
()