2015-06-28 3 views
0

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

Другие процессы/потоки выполняют одну и ту же проверку, но в это время fd равно! = -1. Таким образом, файл не открывается. Затем они продолжают записывать файл. Запись не выполняется большую часть времени и возвращает -1. Когда запись не сработала, я проверил путь к файлу fd с помощью readlink. Путь был другим файлом, кроме файла журнала.

Я предполагаю, что это связано с тем, что хотя значение дескриптора файла всегда равно 11, даже в последующих прогонах это значение относится к другому файлу для каждого процесса. Итак, одиннадцатый файл открыт? Поэтому файл журнала даже не считается открытым для этих процессов, и даже если они открывают файл, fd будет отличаться.

Так что мой вопрос в том, что это правильно? Мой второй вопрос заключается в том, как я затем повторно реализую этот метод, учитывая, что в этот файл журнала необходимо записать несколько процессов. Будет ли каждый процесс открыть этот файл .. или есть другой способ, который является более эффективным .. мне нужно закрыть файл, чтобы другие процессы могли открывать и писать на него ..?

EDIT:

Программное обеспечение представляет собой программное обеспечение с открытым исходным кодом под названием filebench. Файл можно увидеть here.

Метод журнала - filebench_log. Строка 204 - это первая проверка, о которой я упоминал, где файл открыт. Запись происходит на линии 293. Значение fd составляет одиннадцать из всех процессов, и значение одно и то же: 11. Фактически он используется всеми процессами и обычно настраивается here. Файл открывается только один раз (проверяется с помощью операторов печати).

Общая структура данных, которая имеет ФД называется

filebench_shm 

и ФД

filebench_shm->shm_log_fd 

EDIT 2: сообщение об ошибке, что я получаю Плохой дескриптор файла. Errno - 9.

EDIT 3: Таким образом, кажется, что каждый процесс имеет другую таблицу индексов для fds. Wiki:

On Linux, the set of file descriptors open in a process can be accessed under the path /proc/PID/fd/, where PID is the process identifier.

Так что вопрос, который я имею, что для двух процессов с процессом идентификаторы 101, 102 дескриптор файла 11 не то же самое для двух процессов:

/proc/101/fd/11 
/proc/102/fd/11 

I есть общая структура данных между этими процессами .. есть ли другой способ я могу открыть открытый файл между ними, кроме fd, поскольку это не работает?

+0

"* Не удается записать большую часть времени и возвращает -1 *", а 'errno' установлено на какое значение? – alk

+1

"* создает несколько экземпляров *" как? – alk

+1

Некоторый код был бы полезен. Обратите внимание, однако, что, если вы не разместили структуру в общей памяти, она не * разделяется между несколькими процессами. Когда вы создаете дочерние процессы, каждый получает свою собственную * копию *. Всего остального (предполагая, что вы начинаете новые копии с помощью 'fork()' ing). –

ответ

2

Я первоначально написал это в качестве решения:

  • Создать сегмент разделяемой памяти.
  • Поместите переменную дескриптора файла в сегмент.
  • Поместить семафор мютексов в сегмент
  • Каждый процесс обращается к файловому дескриптору в сегменте. Если он не открыт, заблокируйте семафор, проверьте, открыт ли он, и если не открыть файл . Отпустите мьютекс.

Таким образом, все процессы имеют один и тот же дескриптор файла.

Но это предполагает, что основной объект дескриптора файла также находится в общей памяти, что, я думаю, не является.

Вместо этого используйте метод open, затем fork, упомянутый в другом ответе, или каждый процесс открывает файл и использует flock для сериализации доступа, когда это необходимо.

+0

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

+0

Вот почему необходим замок. –

+0

Я добавил замок, и это не помогло. Если вы проверите первую ссылку в редактировании, я добавил (void) ipc_mutex_lock (& ​​filebench_shm-> shm_msg_lock); на строке 202 и разблокировать его после блока if. К сожалению, это не исправить. – user1253073

3

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

+0

Я вызвал метод журнала в ipc_init, где он инициализирует все общие структуры данных и до того, как будут созданы какие-либо другие процессы. Еще одна проблема. Кажется, что для каждого процесса fd приводит к тому, что либо файл не найден, либо заканчивается записью в другой файл, где этот различный файл отличается для каждого процесса. – user1253073

+0

"* запись в другой файл *" как эти файлы отличаются? – alk

+0

Я делаю эту readlink ("/ proc/self/fd/11", filepath, 300); , Как я уже упоминал, значение fd всегда равно 11. Первый раз он печатает правильный путь для файла журнала и записывает его в файл. В большинстве случаев это пустая строка, поэтому ничего не печатается, и я получаю errno = 9. В других случаях я получаю вариацию/fist/upper/bigfileset/00000002/00000001, такую ​​как/fist/upper/bigfileset/00000002/000000013. Поскольку это программное обеспечение файлового архива, он создает кучу файлов/каталогов. Примечание. Я не жестко кодирую fd = 11 в любом месте, кроме описанного выше метода. – user1253073

Смежные вопросы