<html><head><meta http-equiv="Content-Type" content="text/html charset=koi8-r"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>Спасибо, реально разыгрался аппетит :) пошел тырить печеньки у товарищей :)</div><br><div><div>On Jun 5, 2014, at 5:14 PM, Alexander Lourier <<a href="mailto:aml@rulezz.ru">aml@rulezz.ru</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">Запилил за 10 минут. Такие задачки на Go решаются элементарно. А если учесть, что каждая горутина может выполняться на своём CPU и никаких GIL, то становится ням-ням как вкусно.</div><div class="gmail_extra">
<br><br><div class="gmail_quote">5 июня 2014 г., 15:10 пользователь Eugene Toropov <span dir="ltr"><<a href="mailto:eugene.toropov@gmail.com" target="_blank">eugene.toropov@gmail.com</a>></span> написал:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div>Интересно, это уже готовое было или запилил за полчаса?</div><div><br></div><div>Евгений</div><div><div class="h5"><br><div><div>On Jun 5, 2014, at 5:03 PM, Alexander Lourier <<a href="mailto:aml@rulezz.ru" target="_blank">aml@rulezz.ru</a>> wrote:</div>
<br><blockquote type="cite"><div dir="ltr">Минутка рекламы. Вот решение задачи на Go. Оно длинное, потому что я его обильно снабдил комментариями. Если лишнее убрать, всё будет выглядеть очень компактно и работать производительно.<pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><span style="color:rgb(0,136,0);font-weight:bold"><br></span></pre><pre style="color:rgb(51,51,51);margin-top:0px;margin-bottom:0px;line-height:16.25px"><span style="color:rgb(0,136,0);font-weight:bold">package</span> main

<span style="color:rgb(0,136,0);font-weight:bold">import</span> (
        <span style="background-color:rgb(255,240,240)">"fmt"</span>
        <span style="background-color:rgb(255,240,240)">"math/rand"</span>
        <span style="background-color:rgb(255,240,240)">"time"</span>
)

<span style="color:rgb(0,136,0);font-weight:bold">const</span> (
        numWorkers = <span style="color:rgb(0,0,221);font-weight:bold">10</span>
)

<span style="color:rgb(136,136,136)">// task - это задание для воркера.</span>
<span style="color:rgb(0,136,0);font-weight:bold">type</span> task <span style="color:rgb(0,136,0);font-weight:bold">struct</span> {
        value  <span style="color:rgb(51,51,153);font-weight:bold">int</span>
        output <span style="color:rgb(0,136,0);font-weight:bold">chan</span> result
}

<span style="color:rgb(136,136,136)">// result - это результат обработки задания воркером.</span>
<span style="color:rgb(0,136,0);font-weight:bold">type</span> result <span style="color:rgb(0,136,0);font-weight:bold">struct</span> {
        value  <span style="color:rgb(51,51,153);font-weight:bold">int</span>
        worker <span style="color:rgb(51,51,153);font-weight:bold">int</span>
}

<span style="color:rgb(136,136,136)">// worker берёт данные из канала input, обрабатывает их (умножает на 100) и кладёт в канал ответа,</span>
<span style="color:rgb(136,136,136)">// который прислан вместе с заданием.</span>
<span style="color:rgb(0,136,0);font-weight:bold">func</span> worker(workerNumber <span style="color:rgb(51,51,153);font-weight:bold">int</span>, input <span style="color:rgb(0,136,0);font-weight:bold">chan</span> task) {
        <span style="color:rgb(136,136,136)">// Пока входной канал не закроют, читаем из него задание.</span>
        <span style="color:rgb(0,136,0);font-weight:bold">for</span> task := <span style="color:rgb(0,136,0);font-weight:bold">range</span> input {
                <span style="color:rgb(136,136,136)">// Работаем в поте лица.</span>
                time.Sleep(time.Duration(rand.Intn(<span style="color:rgb(0,0,221);font-weight:bold">100</span>)) * time.Millisecond)
                task.output <- result{task.value * <span style="color:rgb(0,0,221);font-weight:bold">100</span>, workerNumber}
        }
}

<span style="color:rgb(136,136,136)">// prepareInput готовит входные задания и кладёт их в два канала: в одну очередь</span>
<span style="color:rgb(136,136,136)">// задания для воркеров, в другую - каналы ответа.</span>
<span style="color:rgb(0,136,0);font-weight:bold">func</span> prepareInput(input <span style="color:rgb(0,136,0);font-weight:bold">chan</span> task, output <span style="color:rgb(0,136,0);font-weight:bold">chan</span> <span style="color:rgb(0,136,0);font-weight:bold">chan</span> result) {
        <span style="color:rgb(0,136,0);font-weight:bold">for</span> i := <span style="color:rgb(0,0,221);font-weight:bold">0</span>; i < <span style="color:rgb(0,0,221);font-weight:bold">100</span>; i++ {
                <span style="color:rgb(136,136,136)">// Канал ответа буферизованный, чтобы воркер не ждал, когда его ответ считают,</span>
                <span style="color:rgb(136,136,136)">// а сразу брался за следующее задание.</span>
                outputChan := <span style="color:rgb(0,112,32)">make</span>(<span style="color:rgb(0,136,0);font-weight:bold">chan</span> result, <span style="color:rgb(0,0,221);font-weight:bold">1</span>)
                <span style="color:rgb(136,136,136)">// Тот факт, что задания кладутся в input и output в одном и том же порядке,</span>
                <span style="color:rgb(136,136,136)">// гарантирует, что ответы будут упорядочены в том же порядке.</span>
                input <- task{i, outputChan}
                output <- outputChan
        }
        <span style="color:rgb(0,112,32)">close</span>(input)
        <span style="color:rgb(0,112,32)">close</span>(output)
}

<span style="color:rgb(0,136,0);font-weight:bold">func</span> main() {
        <span style="color:rgb(136,136,136)">// Каналы обязательно буферизованные (длина буфера = числу воркеров).</span>
        input := <span style="color:rgb(0,112,32)">make</span>(<span style="color:rgb(0,136,0);font-weight:bold">chan</span> task, numWorkers)
        output := <span style="color:rgb(0,112,32)">make</span>(<span style="color:rgb(0,136,0);font-weight:bold">chan</span> <span style="color:rgb(0,136,0);font-weight:bold">chan</span> result, numWorkers)

        <span style="color:rgb(136,136,136)">// Запускаем готовилку входных данных.</span>
        <span style="color:rgb(0,136,0);font-weight:bold">go</span> prepareInput(input, output)

        <span style="color:rgb(136,136,136)">// Запускаем воркеры.</span>
        <span style="color:rgb(0,136,0);font-weight:bold">for</span> i := <span style="color:rgb(0,0,221);font-weight:bold">0</span>; i < numWorkers; i++ {
                <span style="color:rgb(0,136,0);font-weight:bold">go</span> worker(i, input)
        }

        <span style="color:rgb(136,136,136)">// Читаем ответы в порядке, в каком нам нужно.</span>
        <span style="color:rgb(0,136,0);font-weight:bold">for</span> res := <span style="color:rgb(0,136,0);font-weight:bold">range</span> output {
                fmt.Printf(<span style="background-color:rgb(255,240,240)">"%+v\n"</span>, <-res)
        }
}</pre></div><div class="gmail_extra"><br><br><div class="gmail_quote">5 июня 2014 г., 13:46 пользователь Харпалёв Иван <span dir="ltr"><<a href="mailto:ivan.kharpalev@gmail.com" target="_blank">ivan.kharpalev@gmail.com</a>></span> написал:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Добрый день, могучий MoscowPM<div><br></div><div>Опять про параллельную обработку.</div><div><br></div>
<div>
Хочется написать вот такую схему обработки ввода: </div><div>master создаёт work'ов, </div><div>
читает порции из файла, раздаёт порции worker'ам</div><div>ждёт, пока worker обработает, получает ответ worker'a </div><div>пишет результат в файл.</div><div>Так же мастер буфереизует вывод, чтобы выход писался в правильном порядке.</div>


<div><br></div><div>Самое туманное:</div><div>Как передавать данные от мастера к worker'у и Обратно?!!!!</div><div>Как ждать готовности?!!!</div><div>Должна ли такая схема (работа с диском из одного места) дать ускорение по сравнению с чтением/записью файла в каждом worker'е?</div>


<div><br></div><div>смотрел на Coro, увидел Coro::Simaphore, Coro::Signal ... но не пойму:</div><div>  как сделать разделяемую память, (как быстро передавать данные между мастером и worker'ом внутри Perl)?</div><div>

  как сделать неблокирующее ожидание готовности одного из worker'ов (при котором можно заниматься вводом-выводом)?</div>
<div><br></div><div>Подскажите, на чём и как такое писать!!</div><div>Спасибо!</div><div><br></div><div>Уважение</div><div>Иван Харпалев</div><div><br></div><div><br></div></div>
<br>--<br>
Moscow.pm mailing list<br>
<a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org/" target="_blank">http://moscow.pm.org</a><br>
<br></blockquote></div><br></div>
-- <br>Moscow.pm mailing list<br><a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org/" target="_blank">http://moscow.pm.org</a><br></blockquote></div><br></div></div></div>
<br>--<br>
Moscow.pm mailing list<br>
<a href="mailto:moscow-pm@pm.org">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org/" target="_blank">http://moscow.pm.org</a><br>
<br></blockquote></div><br></div>
-- <br>Moscow.pm mailing list<br><a href="mailto:moscow-pm@pm.org">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org">http://moscow.pm.org</a><br></blockquote></div><br></body></html>