Интересно, это уже готовое было или запилил за полчаса?

Евгений

On Jun 5, 2014, at 5:03 PM, Alexander Lourier <[email protected]> wrote:

> Минутка рекламы. Вот решение задачи на Go. Оно длинное, потому что я его 
> обильно снабдил комментариями. Если лишнее убрать, всё будет выглядеть очень 
> компактно и работать производительно.
> 
> package main
> 
> import (
>       "fmt"
>       "math/rand"
>       "time"
> )
> 
> const (
>       numWorkers = 10
> )
> 
> // task - это задание для воркера.
> type task struct {
>       value  int
>       output chan result
> }
> 
> // result - это результат обработки задания воркером.
> type result struct {
>       value  int
>       worker int
> }
> 
> // worker берёт данные из канала input, обрабатывает их (умножает на 100) и 
> кладёт в канал ответа,
> // который прислан вместе с заданием.
> func worker(workerNumber int, input chan task) {
>       // Пока входной канал не закроют, читаем из него задание.
>       for task := range input {
>               // Работаем в поте лица.
>               time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
>               task.output <- result{task.value * 100, workerNumber}
>       }
> }
> 
> // prepareInput готовит входные задания и кладёт их в два канала: в одну 
> очередь
> // задания для воркеров, в другую - каналы ответа.
> func prepareInput(input chan task, output chan chan result) {
>       for i := 0; i < 100; i++ {
>               // Канал ответа буферизованный, чтобы воркер не ждал, когда его 
> ответ считают,
>               // а сразу брался за следующее задание.
>               outputChan := make(chan result, 1)
>               // Тот факт, что задания кладутся в input и output в одном и 
> том же порядке,
>               // гарантирует, что ответы будут упорядочены в том же порядке.
>               input <- task{i, outputChan}
>               output <- outputChan
>       }
>       close(input)
>       close(output)
> }
> 
> func main() {
>       // Каналы обязательно буферизованные (длина буфера = числу воркеров).
>       input := make(chan task, numWorkers)
>       output := make(chan chan result, numWorkers)
> 
>       // Запускаем готовилку входных данных.
>       go prepareInput(input, output)
> 
>       // Запускаем воркеры.
>       for i := 0; i < numWorkers; i++ {
>               go worker(i, input)
>       }
> 
>       // Читаем ответы в порядке, в каком нам нужно.
>       for res := range output {
>               fmt.Printf("%+v\n", <-res)
>       }
> }
> 
> 
> 5 июня 2014 г., 13:46 пользователь Харпалёв Иван <[email protected]> 
> написал:
> Добрый день, могучий MoscowPM
> 
> Опять про параллельную обработку.
> 
> Хочется написать вот такую схему обработки ввода: 
> master создаёт work'ов, 
> читает порции из файла, раздаёт порции worker'ам
> ждёт, пока worker обработает, получает ответ worker'a 
> пишет результат в файл.
> Так же мастер буфереизует вывод, чтобы выход писался в правильном порядке.
> 
> Самое туманное:
> Как передавать данные от мастера к worker'у и Обратно?!!!!
> Как ждать готовности?!!!
> Должна ли такая схема (работа с диском из одного места) дать ускорение по 
> сравнению с чтением/записью файла в каждом worker'е?
> 
> смотрел на Coro, увидел Coro::Simaphore, Coro::Signal ... но не пойму:
>   как сделать разделяемую память, (как быстро передавать данные между 
> мастером и worker'ом внутри Perl)?
>   как сделать неблокирующее ожидание готовности одного из worker'ов (при 
> котором можно заниматься вводом-выводом)?
> 
> Подскажите, на чём и как такое писать!!
> Спасибо!
> 
> Уважение
> Иван Харпалев
> 
> 
> 
> --
> Moscow.pm mailing list
> [email protected] | http://moscow.pm.org
> 
> 
> -- 
> Moscow.pm mailing list
> [email protected] | http://moscow.pm.org

-- 
Moscow.pm mailing list
[email protected] | http://moscow.pm.org

Ответить