Как указывалось ранее, процессы и нити в ядре Linux сводятся к универсальному понятию «задача». Задача, все ресурсы которой (память, открытые файлы и т. д.) используются совместно с другими такими же задачами является «нитью». И наоборот, «процессами» являются такие задачи, которые обладают набором своих частных, индивидуальных ресурсов.
Универсальный системный вызов clone позволяет указать, какие ресурсы станут общими в порождаемой и порождающей задачах, а какие частными. Системные вызовы порождения POSIX-процессов fork и POSIX-нитей pthread_create оказываются в Linux всего лишь «обертками» над clone, что проиллюстрировано в листингах ниже.
В примере из листинга ниже архиватор tar PID=11801 создает при помощи системного вызова clone дочерний процесс PID=11802, в который помещает программу компрессора gzip, используя системный вызов execve. В результате параллельной работы двух взаимодействующих процессов будет создан компрессированный архив docs.tgz каталога /usr/share/doc.
Системный вызов clone—порождение нового процесса
fitz@ubuntu:~$ strace -fa clone,fork,execve tar czf docs.tgz /usr/share/doc
execve(«/bin/tar», [«tar\ «czf», «docs.tgz», «/usr/share/doc»], [/* 24 vars */]) * 0
clone(Process 11802 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, child_tidptr=0xb7df0728) = 11802
tar: Удаляется начальный ‘/’ из имен объектов
[pld 11802] execve(«/bin/gzip», [«gzip»], [/* 24 vars */]) = 0
Process 11801 suspended
Process 11801 resumed
Process 11802 detached
— SIGCHLD (Child exited) @ 0 (0) —
tB примере из ниже компрессор pbzip2 PID=11857 создает при помощи системного вызова clone семь «дочерних» нитей PID=11858->11862, которые имеют общую память CLONE_VM, общие открытые файлы CLONE_FILES и прочие общие ресурсы.
Системный вызов clone — порождение новой нити
fitz@ubuntu:~$ strace -fe clone,fork,execve pbzip2 plan9.iso
execve(«/usr/bin/pbzip2», [«pbzip2», «plan9.iso»], [/* 24 vars */]) = 0
clone(Process 11858 attached (waiting for parent)
Process 11858 resumed (parent 11857 ready)
child_stack=0xb7cb6424,
flags=CLONE_VM | CLONE_FS | CLONE_FILES |CLONE_SICHAND | CLONE_THREAD |CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb7cb6ba8, {entry_number:6, base_addr:0xb7cb6b40, limit:1048575, seg_32bit:l, contents:©, read_exec_only:0, limit_in_pages:l, seg_not_present:0, useable:!}, child_tidptr=0xb7cb6ba8) = 11858
[pid 11857] clone(Process 11859 attached (waiting for parent)
Process 11859 resumed (parent 11857 ready) child_stack=0xb74b5424,
flags=CLONE_VM|CL0NE_FS|CLONE_FILES\CLONE_SIGHANDJ CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTIDjCLONE_CHILD_CLEARTID, parent_tidptr=0xb74b5ba8, {entry_number:6, base_addr:0xb74b5b40, limit:1048575, seg_32bit:l, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:!}, child_tidptr=0xb74b5ba8) = 11859
4X …
[pid 11857] clone(Process 11864 attached (watting for parent)
Process 11864 resumed (parent 11857 ready) chlld_stack=0xb4cb0424,
flags=CLONE_VM| CLONE_FS|CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb4cb0ba8, {entry_number:6,( base_addr:0xb4cb0b40, limit:1048575, seg_32bit:1, contents:0, read_exec_only;0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb4cb©ba8) = 11864
Process 11862 detached
Process 11860 detached
Process 11863 detached
Process 11861 detached
Process 11864 detached
Process 11858 detached
Process 11859 detached