Для создания демона из обычного процесса используется так
называемый double m agic fork (двойной магический форк) — то есть
процесс вначале порождает свою псевдонезависимую копию, ко-
торая потом порождает себя еще раз, тем самым освобождаясь от
породившего процесс терминала, поскольку при закрытии терми-
нала по умолчанию закрываются и порожденные им процессы. Кро-
ме этого производится смена директории по умолчанию для осво-
бождения от окружения. Разберем этот процесс подробнее:
def deamonize (stdout = ' /dev/null', stderr = None, stdin =
'/dev/null', pidfile = None, startmsg= ' started with pid
%s' ):
I I I
Если параметры stdout, stdin не переданы функции, то они
утанавливаются как /dev/null, stderr (ошибки) не выводятся
1 » /
# Делаем первый fork,
try:
pid = os.fork()
if (pid > 0):
sys. exit (0) # Выходим из первого родителя.
except OSError, e:
# В случае ошибки сообщаем об этом
sys.stderr.write("fork#l failed: (%d) %s\n
" %
(e.ermo, e.
strerror))
sys.exit(1)
# Отделяемся от родительского окружения сменяя директорию,
os.chdir(myvar.daemon_place)
os.umask(O)
os.setsidO
# Делаем второй fork,
try:
pid = os.forkO
if (pid > 0):
sys. exit (0) # Выходим из второго родителя.
except OSError, e:
# Отрабатываем возможные ошибки
sys.stderr.write("fork #2 failed: (%d) %s\n"
%
(e.errno,
e.strerror))
sys.exit(1)
Ж
Окончание Начало на стр. 38-39
быстро доступны только данные из стека и некоторые данные из
сегмента данных. Поэтому машинные операции «регистр-регистр»
выполняются намного быстрее, чем операции «регистр-память». Сле-
довательно, для того, чтобы такой код быстро работал, необходи-
мо разместить все необходимые параметры в свободных регистрах
процессора. Благо
их
немало:
а х , в х ,
с х ,
d x , s i , d i . Н о
если да-
же шести регистров не хватает, тогда приходится высвобождать ре-
гистр
в р ,
чтобы можно было использовать и его.
В данном случае необходимо знать, что все обращения к пара-
метрам и локальным переменным внутри подпрограммы осуществля-
ются адресацией через регистр
в р .
Следовательно, если его значе-
ние изменить, то последующее чтение значения переменной может
дать ошибочное значение, а запись в переменную может привести к
сбою работы компьютера, причем это можрг произойти не сразу, а
с задержкой, и место такой ошибки будет трудно выявить. Поэтому
очень важно перед кодом, где значение регистра
в р
будет изменено,
загрузить все используемые локальные переменные в регистры, сохра-
нить в стеке значение
в р
командой
p u s h в р , и
только затем загрузить
данные в регистр
в р .
После того, как некоторые действия с регистром
вр выполнены, следует восстановить его значение из стека инструкци-
ей
p o p в р ,
иначе все последующие обращения к локальным перемен-
ным будут аварийными, и стек останется не выровненным.
Следует отметить еще одну деталь. При указании ассемблерной
инструкции
RET
для выхода из подпрограммы компилятор формирует
машинную команду возврата из подпрограммы в соответствии с ди-
рективой компиляции {$F+)/($F-}, так как служебные слова FAR и
near
применить к ассемблерным подпрограммам невозможно. По
умолчанию ассемблерная подпрограмма рассматривается компиля-
тором как
near,
и любое указание инструкции
RET
компилируется в
машинную команду
retn
(ближний возврат), а иначе — в машинную
команду
retf
(дальний возврат). Однако я хочу предостеречь ат не-
обдуманного использования инструкции
ret,
поскольку ее можно безо-
пасно применять лишь в подпрограммах, которые не задействуют стек.
# Открываем дескриптор файла и пишем стартовое сообщение
if (not stderr):
stderr = stdout
print stdin,stdout,stderr
si= file(stdin, 'r')
so= file(stdout, 'a+')
se = file (stderr, 'a+', 0)
pid = str (os.getpidO )
sys.stderr.write("\n%s\n"% startmsg
%
pid)
sys.stderr.flush()
if pidfile: file(pidfile,'w+').write("%s\n"
%
pid)
# Переопределяем стандартные файловые дескрипторы.
os.dup2(si.fileno(), sys.stdin.filenoO)
os.dup2 (so.fileno(), sys.stdout. filenol))
os.dup2(se.fileno(), sys.stderr.fileno())
Для экономии места я не буду приводить текст функций, а лишь их
названия ниже: Итак, полный текст демона будет выглядеть так:
#! /usr/bin/env python
#
coding: utf8
import sys, os, time
from signal import SIGTERM
import myvar
def deamonize (stdout = '/dev/null', stderr = None, stdin = '/
dev/null', pidfile = None, startmsg = ’ started with pid %s' ):
# Сюда вставить соответствующий код функции (взять выше)
def startstop (stdout=' /dev/null', stderr=None, stdin='/dev/
null', pidf ile= 'pid. txt', startmsg= ' started with pid
%s'
):
# Сюда вставить соответствующий код функции (взять выше)
def test ():
# Сюда вставить соответствующий код функции (взять выше)
if (__name__ssss " main__"):
startstop (stdout=myvar. daemon_log, pidfile=myvar. daemon_pid)
test()
Исходные тексты можно найти по адресам:
* Демон — программа, выступающая в роли службы ОС.
“ Язык программирования Python был так назван своим создате-
лем Гвидо ван Россумом в честь летающего цирка Монти Пайтона.
то есть не имеют входных параметров и локальных переменных и не
возвращают результат строчного типа. Иначе откомпилированная ин-
струкция
ret
при выполнении ее процессором может повлечь за со-
бой непредсказуемые действия. В любом случае подпрограмма будет
успешно завершена, если указать в ее теле перед служебным словом
End
метку, например, с именем
©End
и, в случае необходимости, пре-
рвать выполнение подпрограммы, выполнив условный переход
Jxx
@End
или безусловный переход
JMP @End.
В качестве примера может
служить приведенная выше процедура
FastMove.
Встроенный ассемблер позволяет указывать в инструкциях непо-
средственные данные, представленные в десятичной, двоичной или
шестнадцатеричной системе счисления. При указании данных в де-
сятичном виде достаточно просто указать цифры. Если данные в
двоичном виде, то следует указать каждый бит в виде единицы или
нуля и завершить список бит символом Ь (латинская «би»). Следует
отметить, что если старшие биты числа нулевые, то достаточно ука-
зать значащие младшие биты. При указании данных в шестнадца-
теричном виде следует цифры предварять символом $ (доллар) как
это принято в Паскале, или же в конце числа поставить символ Ь
(латинская «эйч»), как это принято в ассемблере. Если шестнадца-
теричное число в самом старшем разряде содержит букву, а не
цифру, то эту букву следует предварить нулем. Необходимо пом-
нить, что цифры числа любой системы счисления справа означают
младшие разряды, а слева старшие. Вот примеры, где в фигурных
скобках указаны эквивалентные десятичные значения:
пкпгАХ,, 11110000Ь {240}
тснг А Ь , 1111В {15}
тслг В Х, 1111111111111111Ъ {65535}
тсл гС Х , 10 {10},
тсп гС Х , 101г {16}
тсп гС Х , $8 {8}
т о у А Х , ОАО00)1 {40960}
(Продолжение следует)
МОЙ КОМПЬЮТЕР
предыдущая страница 41 Мой Компьютер 2005 08 читать онлайн следующая страница 43 Мой Компьютер 2005 08 читать онлайн Домой Выключить/включить текст