Информация об изменениях

Сообщение Re[3]: Многопоточная обработка потока данных от 06.05.2018 4:28

Изменено 06.05.2018 4:30 Sharowarsheg

Re[3]: Многопоточная обработка потока данных
Здравствуйте, Aniskin, Вы писали:


S>>Нельзя ли сделать очередь на запись, и пусть каждый поток кладет свои обработанные блоки в эту очередь, а еще один поток пусть выбирает из очереди и упорядоченно записывает. Нужно, конечно, будет принять меры, чтобы очередь не распухла, но тем не менее.

A>Можно, конечно, изменить алгоритм на предложенный, но в этом случает при двух потоках первый будет читать и обрабатывать, а второй только писать, imho не очень рационально. В целом, хотелось бы остаться в рамках исходного алгоритма.

откуда вообще два потока? для N процессоров N потоков и три очереди — чтения, готовых, и записи. очередь готовых будет списком, а чтения и записи — очередями FIFO.

читатель -> рабочие -> писатель

пусть читетель не жрёт процессор (а жрёт диск или сеть).
тогда если писатель тоже не жрёт процессор, то рабочих N штук, а если писатель жрёт процессор, то рабочих N-1 штук, но минимум 1

читатель читает блоки с диска и ставит их в очередь чтения. если она слишком длинная, то читатель пропускает ход, делая sleep(сколько-то). когда поставил очередной блок, сигналит событие RE.

рабочие ждут событие RE, и когда оно возникает, просыпаются и смотрят в очередь готовых. если очередь готовых слишком длинная, то они делают sleep() и потом снова смотрят в очередь готовых (потому что события RE следующего может и не быть, если был считан последний блок).

после того, как установлено, что очередь готовых не забита, рабочие смотрят очередь чтения. если она не пуста, то выбирают себе по элементу и начинают обработку. Когда рабочий обработал блок, он ставит этот блок в очередь готовых и сигналит событие RW. после чего рабочий засыпает снова до события RE.

писатель ждет события RW.
когда оно возникает, он блокирует очередь готовых, сортирует ее, и переносит все блоки, которые по порядку можно взять, из очереди готовых в очередь записи. После этого писатель отпускает блокировку очереди готовых, и начинает записывать блоки из очереди записи. После того как все блоки записаны, писатель засыпает снова до события RW (если за время записи успел появиться новый готовый блок, то событие RW будет уже установлено).

такая схема дает максимальную производительность, если читатель и писатель ограничены в основном диском, а рабочие в основом процессором, и если рабочие не зависят от порядка блоков.
Re[3]: Многопоточная обработка потока данных
Здравствуйте, Aniskin, Вы писали:


S>>Нельзя ли сделать очередь на запись, и пусть каждый поток кладет свои обработанные блоки в эту очередь, а еще один поток пусть выбирает из очереди и упорядоченно записывает. Нужно, конечно, будет принять меры, чтобы очередь не распухла, но тем не менее.

A>Можно, конечно, изменить алгоритм на предложенный, но в этом случает при двух потоках первый будет читать и обрабатывать, а второй только писать, imho не очень рационально. В целом, хотелось бы остаться в рамках исходного алгоритма.

откуда вообще два потока? для N процессоров N потоков и три очереди — чтения, готовых, и записи. очередь готовых будет списком, а чтения и записи — очередями FIFO.

читатель -> рабочие -> писатель

пусть читетель не жрёт процессор (а жрёт диск или сеть).
тогда если писатель тоже не жрёт процессор, то рабочих N штук, а если писатель жрёт процессор, то рабочих N-1 штук, но минимум 1

читатель читает блоки с диска и ставит их в очередь чтения. если она слишком длинная, то читатель пропускает ход, делая sleep(сколько-то). когда поставил очередной блок, сигналит событие R.

рабочие ждут событие R, и когда оно возникает, просыпаются и смотрят в очередь готовых. если очередь готовых слишком длинная, то они делают sleep() и потом снова смотрят в очередь готовых (потому что события R следующего может и не быть, если был считан последний блок).

после того, как установлено, что очередь готовых не забита, рабочие смотрят очередь чтения. если она не пуста, то выбирают себе по элементу и начинают обработку. Когда рабочий обработал блок, он ставит этот блок в очередь готовых и сигналит событие W. после чего рабочий засыпает снова до события R.

писатель ждет события W.
когда оно возникает, он блокирует очередь готовых, сортирует ее, и переносит все блоки, которые по порядку можно взять, из очереди готовых в очередь записи. После этого писатель отпускает блокировку очереди готовых, и начинает записывать блоки из очереди записи. После того как все блоки записаны, писатель засыпает снова до события W (если за время записи успел появиться новый готовый блок, то событие W будет уже установлено).

такая схема дает максимальную производительность, если читатель и писатель ограничены в основном диском, а рабочие в основом процессором, и если рабочие не зависят от порядка блоков.