Создать новый процесс
#include <sys/types.h>#include <process.h>pid_t fork( void );
libc
Функция fork() создает новый процесс. Новый (дочерний) процесс является полной копией вызывающего (родительского) процесса, за исключением следующих моментов:
Можно использовать pthread_atfork() для регистрации обработчика функции fork(), который будет вызван перед или после вызова fork().
POSIX требует, чтобы дочерний процесс использовал только функции, безопасные для асинхронных сигналов, до того, как будет вызвана одна из функций exec*(). Если программа использует мьютексы, вероятно, понадобится использовать обработчик pthread_atfork(), который заблокирует все мьютексы перед fork().
При использовании функции fork() ряд сущностей, создающих внутренний мьютекс в момент инициализации, в только что созданном процессе будут иметь неопределенное состояние и их дальнейшее использование крайне не рекомендуется. К ним относятся thread_pool_*(), resmgr_*() (включая обработчики сообщений) и dispatch_*().
Также стоит отметить, что обычное использование функции fork() подразумевает скорейшее использование функций семейства exec*(). В этом случае описанная проблема не будет иметь места. Если же по какой-то причине после fork() не последует указанный вызов, то продолжение использования указанных функций может привести к непредсказуемым последствиям. |
ЗОСРВ
«Нейтрино»
редакции 2020
библиотека libc предоставляет возможность использовать fork() в многопоточных процессах Нулевое значение для дочернего процесса; идентификатор дочернего процесса для родительского процесса. Оба процесса продолжают выполнение от функции fork(). Если возникла ошибка, fork() возвращает -1 родительскому процессу и устанавливает errno.
/** This program executes the program and arguments* specified by argv[1..argc]. The standard input* of the executed program is converted to upper* case.*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <ctype.h>#include <process.h>#include <sys/wait.h>int main( int argc, char **argv ){pid_t pid;pid_t wpid;int fd[2];char buffer[80];int i, len;int status;if ( pipe( fd ) == -1 ){perror( "pipe" );return (EXIT_FAILURE);}if ( ( pid = fork() ) == -1 ){perror( "fork" );return (EXIT_FAILURE);}if ( pid == 0 ){/* This is the child process. Move read end of the pipe to stdin ( 0 ),* close any extraneous file descriptors, then use exec to 'become' the command. */dup2( fd[0], 0 );close( fd[1] );execvp( argv[1], argv + 1 );/* This can only happen if exec fails; print message and exit. */perror( argv[1] );return (EXIT_FAILURE);} else {/* This is the parent process. Remove extraneous file descriptors, read* descriptor 0, write into pipe, close pipe and wait for child to die. */close( fd[0] );while ( ( len = read( 0, buffer, sizeof( buffer ) ) ) > 0 ){for ( i = 0; i < len; i++ ){if ( isupper( buffer[i] ) )buffer[i] = tolower( buffer[i] );}write( fd[1], buffer, len );}close( fd[1] );do {wpid = waitpid( pid, &status, 0 );} while( WIFEXITED( status ) == 0 );return (WEXITSTATUS( status ));}}
POSIX 1003.1
pthread_atfork(), errno, execl(), execle(), execlp(), execlpe(), execv(), execve(), execvp(), execvpe(), spawn(), spawnl(), spawnle(), spawnlp(), spawnlpe(), spawnp(), spawnv(), spawnve(), spawnvp(), spawnvpe(), wait()
Предыдущий раздел: Описание API системной библиотеки