Кіріспе

Компьютерлік техникада процесс өзін-өзі көшіретін операция fork деп аталады. Әсіресе Unix операциялық жүйесі және оған ұқсас жүйелерде, fork – процесс өзін-өзі көшіріп алатын операция. Бұл POSIX және Single UNIX Specification стандарттарына сәйкес келуді талап ететін интерфейс. Ол әдетте ядроның fork, clone немесе басқа жүйелік шақыруларына C стандартты кітапханасының орамасы ретінде жүзеге асырылады. Unix сияқты операциялық жүйелерде процесс құрудың негізгі әдісі – fork.

Шолу

Көп тапсырмалы операциялық жүйелерде процестерге (жұмыс істеп жатқан бағдарламаларға) жаңа процестерді құруға, мысалы, басқа бағдарламаларды іске қосу үшін қажеттілік туады. Форк және оның түрлері Unix сияқты жүйелерде мұны жасаудың негізгі тәсілі болып табылады. Процесс басқа бағдарламаны іске қосуды бастау үшін, ең алдымен өзінің көшірмесін жасайды. Содан кейін, "бала процесі" деп аталатын көшірме, exec жүйелік шақыруын шақырып, өзін басқа бағдарламамен алмастырады: ол бұрынғы бағдарламасын тоқтатып, жаңа бағдарламаның пайдасына жұмыс істейді. Форк операциясы бала процесі үшін жеке адрес кеңістігін құрайды. Бала процесі аталық процестің барлық жад сегменттерінің толық көшірмесіне ие болады. SunOS 4.0 виртуалды жад моделін қолданатын қазіргі заманғы UNIX нұсқаларында "жазу кезінде көшіру" (copy-on-write) механизмі іске асырылған, сондықтан физикалық жадты көшірудің қажеті жоқ. Оның орнына, екі процесс те виртуалды жад беттері физикалық жадтың бірдей беттеріне сілтеме жасай алады, бірақ олардың бірі осы беттен мәлімет оқығанда ғана көшіру жасалады. Бұл оңтайландыру, fork пен exec бірлесіп жаңа бағдарламаны іске қосқанда маңызды рөл атқарады: әдетте, бала процесі жаңа бағдарламаны іске қосу үшін өзінің бағдарламасын тоқтату алдында аз ғана операцияларды орындайды және аталық процестің дерек құрылымдарының өте аз бөлігін ғана қажет етеді. Процесс fork шақырғанда, ол "аталық процесс" деп есептеледі, ал жаңа құрылған процесс оның "баласы" болып саналады. Форктан кейін екі процесс та бірдей бағдарламаны іске қосады және жүйелік шақыруды шақырғандай орындауды жалғастырады. Олар шақырудың қайтарылған мәнін қарап, өздерінің статусын – бала ма, аталық па – анықтап, тиісінше әрекет ете алады.

Тарих

Форк тұжырымдамасы туралы ең алғашқы сілтемелердің бірі 1962 жылы жарық көрген Мелвин Конвейдің «Көппроцессорлық жүйе дизайны» кітабында кездеседі. Конвейдің мақаласы Л. Питер Дойчті GENIE уақытты бөлісу жүйесінде форк іске асыруға ынталандырды, ал осы ұғымды Кен Томпсон Research Unix жүйесінде алғаш рет пайдалану үшін қабылдады. Кейін форк POSIX стандартындағы интерфейске айналды.

Байланыс

Бала процессі ата-ана процессінің файл дескрипторларының көшірмесімен басталады. Процестер аралық байланыс үшін, ата-ана процессі көбінесе бір немесе бірнеше құбырлар құрайды, содан кейін процестер тармақталғаннан кейін олар қажет емес құбырлардың ұштарын жабады.

Vfork (Шығалақ)

Vfork – fork нұсқасы, шақыру конвенциясы мен семантикасы бірдей, бірақ тек шектеулі жағдайларда қолданылады. Unix-тің 3BSD нұсқасында пайда болды, ол виртуалды жадты қолдаған алғашқы Unix болды. Ол POSIX стандартымен бекітілді, бұл vfork-тің fork сияқты әрекет етуіне мүмкіндік берді, бірақ 2004 жылғы нұсқасында қолданыстан шығарылды және кейінгі нұсқаларда posix spawn (әдетте vfork арқылы іске асырылады) деп ауыстырылды. vfork жүйелік шақырылысы жасалғанда, басты процесс бала процесс орындалуын аяқтағанға дейін немесе "exec" жүйелік шақырулар тобының бірі арқылы жаңа орындалатын файлмен алмастырылғанға дейін тоқтатылады. Бала процесс басты процесс жад басқару құрылымын қабылдайды және жад беттері басты және бала процесс арасында көшірме жасалмай бөліседі, әсіресе жазу кезінде көшірме жасалмайды; Сол сияқты, vfork-қа арналған Linux қолданушы нұсқаулығы оны қолдануға қатысты кеңес бермейді: бірақ POSIX спецификациясы олардың «ядро операциялары ретінде жобаланғанын», әсіресе шектеулі аппараттық және нақты уақыт жүйелерінде жұмыс істейтін операциялық жүйелер үшін атап көрсетеді. 4.4BSD нұсқасы vfork іске асырылуын жойды, нәтижесінде vfork fork сияқты әрекет етті, бірақ кейіннен өнімділік себептерімен NetBSD операциялық жүйесінде қайта қалпына келтірілді. Кейбір кіріктірілген операциялық жүйелер, мысалы, uClinux fork-ты жояды және тек vfork-ты іске асырады, себебі олар жад басқару құрылымының болмауына байланысты жазу кезінде көшірме жасау мүмкін емес құрылғыларда жұмыс істеуі керек.

Қайырма

Unix жүйесін жасағандардың құрастырған Plan 9 операциялық жүйесі fork-ты, сондай-ақ, аталық және балалық процестер арасында, оның ішінде адрестік кеңістікті (әр процеске ерекше стек сегментінен басқа), орта айнымалыларын және файлдық жүйе атау кеңістігін қоса алғанда, ресурстарды егжей-тегжейлі бөлісуге мүмкіндік беретін "rfork" деп аталатын нұсқаны да қамтиды; бұл оны процестерді және олардың ішіндегі жіптерді құру үшін бірыңғай интерфейске айналдырады. FreeBSD және IRIX екеуі де Plan 9 жүйесінен rfork жүйелік шақыруын қабылдады, соңғысы оны "sproc" деп атады.

Клоны

clone – Linux ядросындағы жүйелік шақыру, ата-аналық процесспен орындалу контекстінің бөліктерін бөлісетін жаңа процесс құрады. FreeBSD-дің rfork және IRIX-тің sproc сияқты, Linux-тың clone-ы Plan 9-дың rfork-інен шабыттандырылған және жіптерді (threads) іске асыру үшін қолданылуы мүмкін (бірақ қолданба бағдарламашылары көбінесе clone-ның үстінде іске асырылған pthreads сияқты жоғары деңгейдегі интерфейсті пайдаланады). Plan 9 және IRIX-тегі «жеке стектер» мүмкіндігі (Линус Торвальдстың сөзіне сүйенсек) тым көп қосымша шығындар тудыратындықтан алынып тасталды.

Басқа операциялық жүйелерде бұтақтасу

VMS операциялық жүйесінің бастапқы жобасында (1977) жаңа процесс үшін, форк сияқты, бірнеше белгілі бір мекенжайлардың мазмұнын көшіру және кейіннен оларды өзгерту қауіпті деп есептелді. Ағымдағы процесс күйіндегі қателер бағынышты процесске көшірілуі мүмкін. Мұнда процесс тудыру метафорасы қолданылады: жаңа процестің жад құрылымының әрбір бөлігі бастапқыдан жаңадан жасалады. Spawn метафорасы кейіннен Microsoft операциялық жүйелерінде (1993) қабылданды. VM/CMS (OpenExtensions) POSIX үйлесімділік құрамы fork-тың өте шектеулі нұсқасын ұсынады, онда бағынышты процесс орындалғанда аталық процесс тоқтатылады, ал бағынышты және аталық процесс бірдей адрестік кеңістікті пайдаланады. Бұл, по сути, vfork-тың fork ретінде белгіленген түрі. (Бұл тек CMS қонақ операциялық жүйесіне қатысты; Linux сияқты басқа VM қонақ операциялық жүйелері стандартты fork мүмкіндігін ұсынады.)