У меня есть небольшая проблема с родительскими/дочерними процессами в C: как дочерний процесс может получить доступ к файловым дескрипторам, которые родительский процесс открыл после ветвления?
fork о родительском/дочернем процессе
Ответы (5)
Предполагая, что вопрос касается разветвления родительского процесса и последующего открытия новых файловых дескрипторов: краткий ответ: не может.
Существуют специфичные для платформы способы передачи файловых дескрипторов между процессами (например, вспомогательное сообщение SCM_RIGHTS, отправляемое с помощью сокета unix), но они не зависят от отношений родитель-потомок процессов.
Дескрипторы файлов передаются через системный вызов fork
, поэтому дочерний процесс может использовать их по своему усмотрению. Так обычно делается IPC с пайпами (см. man 2 pipe
).
Если вам нужно получить доступ к файловым дескрипторам, открытым после разветвления, вы можете отправить их через сокет UNIX с помощью sendmsg
. См. Как использовать sendmsg() для отправки дескриптора файла через сокеты между двумя процессами?
После fork() дочерний процесс получает свою собственную копию файловых дескрипторов родителя.
Каждый из дочерних файловых дескрипторов ссылается на одно и то же описание открытого файла с соответствующим файловым дескриптором родителя.
Когда у них есть собственные копии файловых дескрипторов, отношения потомок/родитель не имеют значения. Это то же самое, как если бы два разных процесса обращались к одному и тому же файлу с собственным набором файловых дескрипторов. После чего может вступить в действие блокировка файлов и синхронизация.
[отредактировано - Извините, неправильно прочитал вопрос, вы не можете, поскольку процессы не используют одно и то же пространство памяти. Лучше всего, если вы откроете дескриптор файла перед разветвлением или используете какой-либо другой механизм IPC в зависимости от того, чего вы пытаетесь достичь]
Дочерний процесс наследует файловые дескрипторы родителя и поэтому может использоваться напрямую.
void example()
{
int fd = open("My file", O_WRONLY );
pid_t pid = fork();
if(pid == 0)
{
/* child */
char * child_msg = "Hi there from child\n";
write(fd, my_msg, sizeof(my_msg);
/* ... other stuff */
}
else
{
/* parent */
char * parent_msg = "Hi there from parent\n";
write(fd, my_msg, sizeof(my_msg);
/* ... other stuff */
}
}
Оба сообщения будут записаны в «мой файл».
Ваш вопрос не ясен.
В любом случае, если вы пытаетесь использовать данные в дочернем процессе, который использует родителя, вы можете передавать данные от родителя к дочернему. Для упрощения просто используйте анонимные каналы в POSIX int pipe(int anFD[2])
, а затем вы можете использовать write
и read
(из функций fread
и fwrite
). В родительском процессе вы должны использовать функцию popen
, чтобы открыть файл с доступом для записи/чтения.
Помните, что fork()
делает полную копию (родительский и дочерний элементы имеют общие страницы, и эти страницы доступны только для чтения). Если вы пытаетесь писать на исходной странице, ядро проверит, является ли дочерний процесс единственным владельцем, и тогда эта исходная страница будет доступна для записи).
popen()
— это механизм передачи данных в процесс или из него, а не в файл, и использование этой функции не является обязательным. Вам нужно проделать некоторую работу (возможно, с fdopen()
), чтобы использовать fwrite()
и fread()
на канале. Они используют файловые потоки, но pipe()
возвращает файловые дескрипторы.
- person Jonathan Leffler; 21.01.2013
fork()
. Обычно текст (код) доступен только для чтения, но данные помечены как COW — копирование при записи — так что они копируются только тогда, когда один из процессов изменяет данные.
- person Jonathan Leffler; 21.01.2013