fork о родительском/дочернем процессе

У меня есть небольшая проблема с родительскими/дочерними процессами в C: как дочерний процесс может получить доступ к файловым дескрипторам, которые родительский процесс открыл после ветвления?


person user1995143    schedule 20.01.2013    source источник
comment
Ваш вопрос немного не ясен. Родительский процесс открывает файлы, а затем разветвляет или разветвляет, а затем открывает файлы?   -  person Mat    schedule 21.01.2013
comment
затем вилка родительского процесса открывает файлы, так как же дочерний процесс может использовать эти файлы?   -  person user1995143    schedule 21.01.2013
comment
Антон ответил правильно. Нет портативного способа сделать это, вам понадобятся API-интерфейсы для конкретной ОС.   -  person Mat    schedule 21.01.2013


Ответы (5)


Предполагая, что вопрос касается разветвления родительского процесса и последующего открытия новых файловых дескрипторов: краткий ответ: не может.

Существуют специфичные для платформы способы передачи файловых дескрипторов между процессами (например, вспомогательное сообщение SCM_RIGHTS, отправляемое с помощью сокета unix), но они не зависят от отношений родитель-потомок процессов.

person Anton Kovalenko    schedule 20.01.2013

Дескрипторы файлов передаются через системный вызов fork, поэтому дочерний процесс может использовать их по своему усмотрению. Так обычно делается IPC с пайпами (см. man 2 pipe).

Если вам нужно получить доступ к файловым дескрипторам, открытым после разветвления, вы можете отправить их через сокет UNIX с помощью sendmsg. См. Как использовать sendmsg() для отправки дескриптора файла через сокеты между двумя процессами?

person andyn    schedule 20.01.2013

После fork() дочерний процесс получает свою собственную копию файловых дескрипторов родителя.

Каждый из дочерних файловых дескрипторов ссылается на одно и то же описание открытого файла с соответствующим файловым дескриптором родителя.

Когда у них есть собственные копии файловых дескрипторов, отношения потомок/родитель не имеют значения. Это то же самое, как если бы два разных процесса обращались к одному и тому же файлу с собственным набором файловых дескрипторов. После чего может вступить в действие блокировка файлов и синхронизация.

person sr01853    schedule 20.01.2013

[отредактировано - Извините, неправильно прочитал вопрос, вы не можете, поскольку процессы не используют одно и то же пространство памяти. Лучше всего, если вы откроете дескриптор файла перед разветвлением или используете какой-либо другой механизм 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 */
    }
}

Оба сообщения будут записаны в «мой файл».

person Peter L    schedule 20.01.2013
comment
моя проблема заключается в использовании файловых дескрипторов, созданных родителем ПОСЛЕ разветвления, я знаю, что файловые дескрипторы, открытые ДО разветвления, наследуются дочерним элементом. - person user1995143; 21.01.2013
comment
Извините, неправильно прочитал вопрос, вы не можете. - person Peter L; 21.01.2013

Ваш вопрос не ясен.

В любом случае, если вы пытаетесь использовать данные в дочернем процессе, который использует родителя, вы можете передавать данные от родителя к дочернему. Для упрощения просто используйте анонимные каналы в POSIX int pipe(int anFD[2]), а затем вы можете использовать write и read (из функций fread и fwrite). В родительском процессе вы должны использовать функцию popen, чтобы открыть файл с доступом для записи/чтения.

Помните, что fork() делает полную копию (родительский и дочерний элементы имеют общие страницы, и эти страницы доступны только для чтения). Если вы пытаетесь писать на исходной странице, ядро ​​​​проверит, является ли дочерний процесс единственным владельцем, и тогда эта исходная страница будет доступна для записи).

person zerospiel    schedule 20.01.2013
comment
Добро пожаловать в Stack Overflow. Обратите внимание, что вопросы и ответы должны быть написаны на полуофициальном английском языке без сокращений в стиле SMS, таких как «ur» и «u». Я обновил на этот раз; вы должны сделать это сами в следующий раз. У вас также есть некоторые проблемы; popen() — это механизм передачи данных в процесс или из него, а не в файл, и использование этой функции не является обязательным. Вам нужно проделать некоторую работу (возможно, с fdopen()), чтобы использовать fwrite() и fread() на канале. Они используют файловые потоки, но pipe() возвращает файловые дескрипторы. - person Jonathan Leffler; 21.01.2013
comment
Родительский и дочерний процессы действительно совместно используют страницы после fork(). Обычно текст (код) доступен только для чтения, но данные помечены как COW — копирование при записи — так что они копируются только тогда, когда один из процессов изменяет данные. - person Jonathan Leffler; 21.01.2013