LINUX.ORG.RU

Редактирование файлов несколькими процессами


0

0

Есть програмуллина которая запускается на несколько процессов и сидит в памяти ( написана на gcc ) Ее основная задача при каком то запросе к ней писать что то в лог файл ... Как сделать так, чтобы можно было без опасения открывать один и тот же файл-лог на запись несколькими процессами, чтобы записи не перемещивались а шли по порядку ???

anonymous

> man open  
...
O_APPEND
Файл открывается в режиме добавления.  Перед каждым write,  файловый
указатель  перемещается  в  конец  файла,  как если бы использовался
lseek.  O_APPEND может привести к  повреждению  файлов  на  файловой
 системе  NFS, если несколько процессов одновременно добавляют данные
в один файл.  Это происходит из-за того,  что  NFS  не  поддерживает
добавление в файл, поэтому ядро на машине-клиенте должно эмулировать
 эту поддержку, что не может быть выполнено без race condition.

Еще нужно обязательно сделать блокировку на этап записи, чтоб в один
промежуток времени только один процесс мог писать, в файл.
> man fcntl

anonymous
()
Ответ на: комментарий от vnp

Точно, либо syslog или fcntl смотрите про блокировку одновременного доступа.

SatanClaus ★★★
()
Ответ на: комментарий от anonymous

> Еще нужно обязательно сделать блокировку на этап записи,
> чтоб в один промежуток времени только один процесс мог писать

не нужно если O_APPEND

про nfs я мало что знаю, но, кажется, на сегодняшний
день O_APPEND без O_DIRECT работает.

если кто знает точно - поправьте

idle ★★★★★
()
Ответ на: комментарий от idle

>не нужно если O_APPEND

А почему не нужно ?
Флажек O_APPEND говорит вроде, что добавлять в конец файла.
Но ведь при записи файл разве блокируется ?
Если одна строчка то возможно, чтение запись низкоуровневая
вроде атомарная операция, а если
одновременно несколько процессов пишут и не одну строчку а 
блок данных(несколько строчек). Разве не произойдет накладка ?
Это скорее вопрос, а не спор налив глаза. :)

anonymous
()
Ответ на: комментарий от anonymous

> > не нужно если O_APPEND
>
> А почему не нужно ?

в 2.6 код несколько сложнее из-за aio, поэтому проще
посмотреть в 2.4 mm/filemap.c:generic_file_write():
        ...
        down(&inode->i_sem);
        ...
        if (file->f_flags & O_APPEND)
                pos = inode->i_size;

поэтому и не нужно, т.к. write всегда происходит
при взятом inode->i_sem семафоре.

idle ★★★★★
()
Ответ на: комментарий от idle

Это об одном write() идет речь, как я понял.
А если и цикле делать несколько write() подряд.
...
struct ZZ {
  char  name[10];
  int   yy;
}  buf[10];
....

 if (fork()==0)
  { 
    ... инициализация buf

    for(int nI=0; nI<10; nI++)
      write(id, buf[nI], sizeof(ZZ));

  } //if()

 ... инициализация buf
for(int nI=0; nI<10; nI++)
  write(id, buf[nI], sizeof(ZZ));

Пусть дурацкий пример но разве в таком случае записи не перемешаются ?

anonymous
()
Ответ на: комментарий от anonymous

> разве в таком случае записи не перемешаются ?

мы, кажется, о разном говорим. конечно 10 write()'ов не
могут выполниться атомарно без синхронизации. но, если
O_APPEND, _каждая_ запись пойдет в конец файла, даже если
этот файл был открыт в разных процессах, и для этого не
нужно блокировок.

idle ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.