Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> семафор, синхронизация процессов, fork, IPC::SysV 
:(
    Опции темы
FooBar
Дата 30.7.2008, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



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

Код

#!/usr/bin/perl
use warnings;
use strict;
use IPC::SysV qw(IPC_CREAT IPC_PRIVATE IPC_RMID);

open(FILE, '<4test') || die $!;

my $id = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT ) || die $!; #создаем семафор
semop($id, pack("s3", 0, +1, 0)) || die $!; #открываем его

my (@childs, $pid);
for (0..2)
{
    $pid = fork; #тут собственно форкаемся
    die $! unless defined $pid;
    unless ($pid)
    {
        open(TMP, '>/tmp/'.$$) || die $!; #и открываем файл
        while (1)
        {
            semop($id, pack("s3", 0, -1, 0)) || die $!; #опускаем семафор
            my $string = <FILE>;                                #читаем строку
            semop($id, pack("s3", 0, +1, 0)) || die $!; #поднимаем семафор
            last unless defined $string;
            print TMP $string;
        }
        close TMP;
        close FILE;
        exit(0)
    }
    else
    {
        push(@childs, $pid)
    }
}

close FILE;
waitpid($_, 0) for (@childs); #ждем детишек

semctl($id, 0, IPC_RMID, 0) || die $!; #удаляем семафор



а вот что я наблюдаю в файлах:
Код

один файл:
5
add5efc3f8de35d6208dc6fc154b59d3
другой:
2aeb3faaf76e04a953f9369bdeecbeb9
af063d75c14a83239da1b396
545a2296a05d382354887c2886ea50d5
и т.д.

то есть строки повредились

исходный тестовый файл был создан таким образом:
Код

use MD5;

for $i (1..300000) {
    print MD5->hexhash($i)."\n";
}



с отключением буферизации я эксперементировал, не помогло если просто без семафоров читать, то результат такой же, может быть здесь стоит применить flock, но кукбук говорит что блокировка исчезает только после закрытия файла, что в данном случае недопустимо.
собственно вопрос в том как добиться нормально чтения строк из файла несколькими процессами с сохранением смещения
PM MAIL   Вверх
sir_nuf_nuf
Дата 30.7.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



FooBar, зачем вам семафор ?
Читать можно и без блокировки файла.
у всех процессов будет правда общее смещение в файле...


Это сообщение отредактировал(а) sir_nuf_nuf - 30.7.2008, 15:31


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
FooBar
Дата 30.7.2008, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



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

PM MAIL   Вверх
sir_nuf_nuf
Дата 30.7.2008, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



упс.. я вам наврал =)
все как раз наоборот - у них будет общий файловый дескриптор, и смещение будет общим.
сейчас подумаю..



--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
arto
Дата 30.7.2008, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



my $cnt = 0
my @a = grep { ++$cnt/3 == 0 } <F>;

my @a = grep { ++$cnt/3 == 1 } <F>;

my @a = grep { ++$cnt/3 == 2 } <F>;

?

PM MAIL ICQ   Вверх
IceSunrise
Дата 30.7.2008, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 7.4.2008
Где: Санкт-Петербург

Репутация: 3
Всего: 3



вы хотите, чтобы они строго последовательно считывали строки?
PM MAIL   Вверх
sir_nuf_nuf
Дата 30.7.2008, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



FooBar, я так подумал, что не получится открывать файл один раз, а потом его дескриптор наследовать при форке.
Вот почему:
для чтения вы используете оператор <>
этому оператору нужно как-то найти конец строки в файле, поэтому он читает блоками 
(не проверял, но здравый смысл подсказывает, что не посимвольно =))
Когда считывается блок из файла - есть вероятность прочитать более одной строки,
при это смещение увеличивается и указывает на середину следующей строки.
Поэтому следующий процесс получает битую строку.

Отключение буферизации может и не помочь в таком случае.

Решения видно 2:

а) каждый потомок открывает свой дескриптор и читает из него. Выбирает каждую 3ю строку, как показал arto
б) читать не построчно, а блоками фиксированной длинны.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
FooBar
Дата 30.7.2008, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



sir_nuf_nuf, спасибо, похоже вы прояснили ситуацию, меня интересовало почему так происходит, а для практической реализации можно использовать и другие алгоритмы
IceSunrise, задумка была в считывании построчно на ходу (не читая заранее весь файл) и распределении между процессами, примерно так:
1 aaa
2 bbb
3 ccc
4 ddd
5 eee
6 fff

1 процесс:
aaa
ccc
2 процесс:
bbb
ddd
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1404 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.