Системное программирование в UNIX средствами Free Pascal

       

подобно Fork, создает дочерний процесс,


uses linux;
TCloneFunc=function(args:pointer):longint;cdecl;
Clone(func:TCloneFunc;sp:pointer;flags:longint;args:pointer):longint;
Clone, подобно Fork, создает дочерний процесс, являющийся копией родительского. Однако, в отличие от Fork, процесс-потомок совместно с родителем использует некоторые части контекста, что делает его подходящим для реализации потоков: множества экземпляров программы, разделяющих общую память.
При создании потомка запускается функция Func, которой передаются параметры Args. Возвращаемым значением Func является код завершения потомка.
Указатель sp
хранит адрес памяти, зарезервированной под стек дочернего процесса.
Параметр Flags определяет поведение вызова Clone. Младший байт Flags содержит номер сигнала, который будет послан родителю при завершении потомка. Он может быть объединен с помощью побитового ИЛИ со следующими константами:
CLONE_VM               Родитель и потомок разделяют память, включая отображенную вызовом mmap.
CLONE_FS               Родитель и потомок разделяют параметры файловой системы; вызовы chroot, chdir и umask действуют на оба процесса.
CLONE_FILES         Таблица дескрипторов файлов разделяется родителем и потомком.
CLONE_SIGHAND     Таблица обработчиков сигналов разделяется родителем и потомком, однако маски сигналов различаются.
CLONE_PID             Родитель и потомок имеют одинаковый pid.


Clone возвращает идентификатор потомка или -1 в случае ошибки, устанавливая значение linuxerror в Sys_EAGAIN (слишком много процессов) и Sys_ENOMEM (недостаточно памяти для создания дочернего процесса).
Пример использования Clone:
uses
  Linux, Errors, crt;
const
  Ready : Boolean = false;
  aChar : Char    = 'a';
function CloneProc( Arg: Pointer ): LongInt; Cdecl;
begin
  WriteLn('Hello from the clone ',PChar(Arg));
  repeat
    Write(aChar);
    Select(0,0,0,0,600);
  until Ready;
  WriteLn( 'Clone finished.');
  CloneProc := 1;
end;
var
  PID : LongInt;
procedure MainProc;


begin
а WriteLn(' cloned process PID: ', PID );
а WriteLn('Press <ESC> to kill ... ' );
а repeat
ааа Write('.');
ааа Select(0,0,0,0,300);
ааа if KeyPressed then
ааааа case ReadKey of
ааааааа #27: Ready := true;
ааааааа 'a': aChar := 'A';
ааааааа 'A': aChar := 'a';
ааааааа 'b': aChar := 'b';
ааааааа 'B': aChar := 'B';
ааааа end;
а until Ready;
а WriteLn('Ready.');
end;
const
а StackSze = 16384;
а theFlags = CLONE_VM+CLONE_FS+CLONE_FILES+CLONE_SIGHAND;
а aMsgаааа : PChar = 'Oops !';
var
а theStack : Pointer;
а ExitStat : LongInt;
begin
а GetMem(theStack,StackSze);
а PID := Clone(@CloneProc,
аааааааааааааа Pointer( LongInt(theStack)+StackSze),
ааааааааа аааааtheFlags,
аааааааааааааа aMsg);
а if PID < 0 then
ааа WriteLn('Error : ', LinuxError, ' when cloning.')
а else
ааа begin
ааа MainProc;
ааа case WaitPID(0,@ExitStat,Wait_Untraced or wait_clone) of
ааааа -1: WriteLn('error:',LinuxError,'; ',StrError(LinuxError));
аааааа 0: WriteLn('error:',LinuxError,'; ',StrError(LinuxError));
ааа else
ааааа WriteLn('Clone exited with: ',ExitStat shr 8);
ааа end;
ааа end;
а FreeMem( theStack, StackSze );
end.

Содержание раздела