![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
Итак, это первый из 6 уроков по программированию на C(именно на С а не на C++) в Linux.
Этот урок посвящен механизму сигналов в Linux. Как известно сигнал - это способ передачи данных (ну не совсем) между процессами. Отличительная особенность сигнала в том, что посылать/принимать сигналы можно только в пределах одного компьютера. По сети или интернет использовать сигналы нельзя. Отличительная особенность сигналов в том, что их обработка происходит сразу после отправки/получения (или не происходит вовсе). Есть два типа сигналов. Классические (31 шт.) и реального времени. В данном уроке я расскажу только о некоторых классических сигналах. Об остальных вы можете прочитать в книге Майкл. К. Джонсон и Эрик В. Троан - "Разработка приложений в среде Linux" (Глава 12 - Обработка сигналов) Скачать Сигналы (классические): Сигнал SIGHUP (номер 1) изначально был предназначен для того, чтобы информировать программу о потере связи с управляющим терминалом (терминалы часто подключались к системе с помощью модемов, так что название сигнала происходит от hung up – повесить трубку). Сигнал SIGHUP посылается приложению так же и в том случае, если процесс-лидер сессии завершил свою работу. Многие программы-демоны, у которых нет лидера сессии, так же обрабатывают этот сигнал. В ответ на получение SIGHUP демон обычно перезапускается (или просто повторно читает файл конфигурации). По умолчанию программа, получившая этот сигнал, завершается. Сигнал SIGINT (номер 2) обычно посылается процессу, если пользователь терминала дал команду прервать процесс (обычно эта команда – сочетание клавиш Ctrl-C) . Сигнал SIGABRT (номер 6) посылается программе в результате вызова функции abort(3). В результате программа завершается с сохранением на диске образа памяти. Сигнал SIGKILL (номер 9) завершает работу программы. Программа не может ни обработать, ни игнорировать этот сигнал. Сигнал SIGSEGV (номер 11) посылается процессу, который пытается обратиться к не принадлежащей ему области памяти. Если обработчик сигнала не установлен, программа завершается с сохранением на диске образа памяти. Сигнал SIGTERM (номер 15) вызывает «вежливое» завершение программы. Получив этот сигнал, программа может выполнить необходимые перед завершением операции (например, высвободить занятые ресурсы). Получение SIGTERM свидетельствует не об ошибке в программе, а о желании ОС или пользователя завершить ее. Сигнал SIGCHLD (номер 17) посылается процессу в том случае, если его дочерний процесс завершился или был приостановлен. Родительский процесс также получит этот сигнал, если он установил режим отслеживания сигналов дочернего процесса и дочерний процесс получил какой-либо сигнал. По умолчанию сигнал SIGCHLD игнорируется. Сигнал SIGCONT (номер 18) возобновляет выполнение процесса, остановленного сигналом SIGSTOP. Сигнал SIGSTOP (номер 19) приостанавливает выполнение процесса. Как и SIGKILL, этот сигнал не возможно перехватить или игнорировать. Сигнал SIGTSTP (номер 20) приостанавливает процесс по команде пользователя (обычно эта команда – сочетание клавиш Ctrl-Z). Сигнал SIGIO/SIGPOLL (в Linux обе константы обозначают один сигнал – номер 29) сообщает процессу, что на одном из дескрипторов, открытых асинхронно, появились данные. По умолчанию этот сигнал, как ни странно, завершает работу программы. Итак, задача. Нам нужно организовать прием/передачу сигналов между двумя процессами. Но процессы у нас не простые. Один порождает другой. То есть один процесс будет родительским, а второй - дочерним. Итак, начнем. ОС - Ubuntu Linux, компилятор - gcc. Первый шаг - напишем функцию, которая будет порождать дочерний процесс. Как известно, в Linux процессы порождаются функцией fork. Она клонирует текущий процесс. Чтобы сделать процесс, который выполняет другой код, нужно использовать функцию из семейства exec. Код:
Если fork вернет 0, это значит что процесс клонировался, и мы сейчас находимся в порожденном процессе. В данном случае мы вызываем функцию execl, которая назначает порожденному процессу новый исполняемый файл. Код, который идет дальше - это код, который выполняет текущий процесс. Дальше мы будем отправлять порожденному процессу сигналы. В качестве рабочего сигнала я выбрал SIGHUP. Посылка сигнала выполняется с помощью функции kill(согласен, не сильно благозвучное название ![]() Последний раз редактировалось MaTBeu; 07.04.2009 в 00:33. |
![]() |
![]() |
![]() |
#2 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
//----------------------Продолжение----------------------------
Итак, код, идущий за предыдущим куском Код:
Дальше мы отправляем дочернему процессу сигнал SIGTERM - сигнал аварийного завершения. Следующие 6 строк кода устанавливают обработчики для разных сигналов. Первый параметр функции signal - это сигнал, которому присваивается обработчик. Второй параметр - указатель на функцию-обработчик. Если второй параметр SIG_IGN, то сигнал игнорируется. Мы устанавливаем обработчики только для двух сигналов - SIGHUP и SIGTERM. Обрабатывать их будет функция signal_handler. Вот ее код Код:
Полный код родительского процесса Parent.c Код:
Код:
Последний раз редактировалось MaTBeu; 07.04.2009 в 00:28. |
![]() |
![]() |
![]() |
#3 |
Форумчанин
Регистрация: 24.11.2007
Сообщений: 196
|
![]()
Хорошая статья. Спасибо.
Буду ждать продолжения. |
![]() |
![]() |
![]() |
#4 |
search money
Пользователь
Регистрация: 12.10.2009
Сообщений: 46
|
![]()
Здравствуйте, у меня такая проблема, когда компилирую программу, используя 2 .cpp файла из статьи, у меня происходят такие чудеса(постоянно разные результаты), вот бывает 3 варианта вывода:
1. ![]() 2. ![]() 3. Это нормальный результат, то что и должно выдавать ![]() Подскажите пожалуйста в чем может быть проблема. ЗЫ. использую Ubuntu 11.10 и QT 2.4.1 Последний раз редактировалось savra; 19.04.2012 в 21:55. |
![]() |
![]() |
![]() |
#5 |
Новичок
Джуниор
Регистрация: 27.10.2014
Сообщений: 1
|
![]()
спс, полезно
|
![]() |
![]() |
![]() |
Опции темы | Поиск в этой теме |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Как принимать сигналы с ИК передатчика | Вырвиглаз | Компьютерное железо | 7 | 29.03.2009 23:16 |
Нужны уроки | beygul | Свободное общение | 0 | 26.10.2008 14:57 |
Мультимедийные уроки Linux | Roman | Linux (Ubuntu, Debian, Red Hat, CentOS, Mint) | 2 | 24.10.2008 11:40 |
Linux на VMware....... WinXP <-> Linux | DMUTPUU | Операционные системы общие вопросы | 1 | 24.09.2008 12:03 |