LINUX.ORG.RU

IO & threads


0

0

Что будет лучше А или Б по архитектуре/производительности (интересует последний пункт):

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

Б. 1. один тред слушает сокет и помещает все принятые данные в очередь
2. данные извлекаются из очереди другим тредом и отдаются на обработку тредам из пула
3. каждый тред из пула после обработки данных помещает ресультаты в очередь для отправления
4. тред который принимает данные из очереди результатов и отправляет используя сокет из п.1

anonymous


да в общем то пофигу. сокет то один и в п.1 доступ к нему все равно должен синхронизоваться.

// wbr

klalafuda ★☆☆
()

Второй способ сложнее, потому что придётся обходить вариант с перегрузкой, если данные не успевают отправляться: соединение на отправку может работать медленнее, чем на приём, из-за этого в наивной реализации получаем неограниченный рост очереди с исчерпанием доступной памяти.

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

anonymous
()
Ответ на: комментарий от klalafuda

>да в общем то пофигу.

согласен на все 100. Покуда будет 1 сокет, городить весь этот колхоз не имеет ни малейшего смысла. Единственное исключение - это если каждый пакет данный, пришедший по сокету, требует нееб^W очень большой обработки, да и этот вариант целесообразен только на SMP.

Deleted
()

Кстати, пункт 2 в каждом варианте лишний.
Почему бы тредам из пула самим не снимать данные из очереди?

тред, читающий из сокета (псевдокод):

Queue queue;
Mutex queue_mutex;
Cond queue_cond;

for (;;) {
    msg = read();

    queue_mutex.lock ();
    queue.add (msg);
    queue_cond.signal ();
    queue_mutex.unlock ();
}

треды из пула:

for (;;) {
    queue_mutex.lock ();

    while (queue.isEmpty ())
        queue_cond.wait (queue_mutex);

    msg = queue.dequeue ();

    queue_mutex.unlock ();

    process (msg);
}

anonymous
()
Ответ на: комментарий от anonymous

если трэд из пула однократно вызывает send, то всё равно. если он send-ит свои данные по кускам - тут данные разных трэдов могут смешаться; второй вариант будет надежнее.


>Почему бы тредам из пула самим не снимать данные из очереди?
я так понимаю, "отдаются на обработку тредам из пула" означает, что они (данные) расфасовываются по нескольким очередям (по одной для каждого трэда)



вообще, данная архитектура довольно надежная, только:
1) я бы создавал расфасовочный трэд только, если первый принял какие-то данные; и чтобы этот второй уничтожал себя, когда очередь пуста.
ну или либо очень хорошо бы подумал, как его "заснуть" при отсутствии данных.
2) то же самое для трэдов из пула.
3) очередь(и) бы сделал динамической(ими), но до определенного потолка (в зависимости от задач)
4) предусмотрел бы в программе и в протоколе случай, когда исходящие данные накапливаются быстрее, чем успевают отправляться...
к тому же модель довольно примитивна, вполне можно прогнать в любом языке моделирования.

xydo ★★
()
Ответ на: комментарий от xydo

>второй вариант будет надежнее.
забыл добавить: с мютексами между каждым этапом, разумеется...

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.