| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: Общие вопросы > семафор, синхронизация процессов |
| Автор: FooBar 30.7.2008, 14:07 | ||||||
Здравствуйте, у меня вот такой вопрос, я открываю файл в родительском процессе, далее fork создаю 3 потомка которые читают из этого файла строки и записывают их каждый в свой файл:
а вот что я наблюдаю в файлах:
то есть строки повредились исходный тестовый файл был создан таким образом:
с отключением буферизации я эксперементировал, не помогло если просто без семафоров читать, то результат такой же, может быть здесь стоит применить flock, но кукбук говорит что блокировка исчезает только после закрытия файла, что в данном случае недопустимо. собственно вопрос в том как добиться нормально чтения строк из файла несколькими процессами с сохранением смещения |
| Автор: sir_nuf_nuf 30.7.2008, 14:39 |
| FooBar, зачем вам семафор ? Читать можно и без блокировки файла. у всех процессов будет правда общее смещение в файле... |
| Автор: FooBar 30.7.2008, 14:51 |
| sir_nuf_nuf, >У каждого процесса будет свое смещение в файле. мне то как раз нужно чтобы у них было общее смещение, то есть если первый процесс прочел первую строку из файла, то второй прочитает вторую, и так далее |
| Автор: sir_nuf_nuf 30.7.2008, 15:13 |
| упс.. я вам наврал =) все как раз наоборот - у них будет общий файловый дескриптор, и смещение будет общим. сейчас подумаю.. |
| Автор: arto 30.7.2008, 15:30 |
| my $cnt = 0 my @a = grep { ++$cnt/3 == 0 } <F>; my @a = grep { ++$cnt/3 == 1 } <F>; my @a = grep { ++$cnt/3 == 2 } <F>; ? |
| Автор: IceSunrise 30.7.2008, 15:34 |
| вы хотите, чтобы они строго последовательно считывали строки? |
| Автор: sir_nuf_nuf 30.7.2008, 15:40 |
| FooBar, я так подумал, что не получится открывать файл один раз, а потом его дескриптор наследовать при форке. Вот почему: для чтения вы используете оператор <> этому оператору нужно как-то найти конец строки в файле, поэтому он читает блоками (не проверял, но здравый смысл подсказывает, что не посимвольно =)) Когда считывается блок из файла - есть вероятность прочитать более одной строки, при это смещение увеличивается и указывает на середину следующей строки. Поэтому следующий процесс получает битую строку. Отключение буферизации может и не помочь в таком случае. Решения видно 2: а) каждый потомок открывает свой дескриптор и читает из него. Выбирает каждую 3ю строку, как показал arto б) читать не построчно, а блоками фиксированной длинны. |
| Автор: FooBar 30.7.2008, 16:02 |
| sir_nuf_nuf, спасибо, похоже вы прояснили ситуацию, меня интересовало почему так происходит, а для практической реализации можно использовать и другие алгоритмы IceSunrise, задумка была в считывании построчно на ходу (не читая заранее весь файл) и распределении между процессами, примерно так: 1 aaa 2 bbb 3 ccc 4 ddd 5 eee 6 fff 1 процесс: aaa ccc 2 процесс: bbb ddd |