Пишу прожку коллектор пакетов NetFlow. Она через открытый UDP сокет принимает пакеты и я попробывал добавить в неё многопоточность. На самом деле мне нужно, чтобы использовались для обработки полученных данных ресурсы параллельно двух процов.Сделано это такой конструкией:
--------------------------------------------------------------------
struct sockaddr_in from;
socklen_t from_len;
int mtu;
char *buf;
int s;// Тут начинаю бесконечный цикл для ожидания поступивших пакетов
// Сокет был открыт ранееwhile(1)
{
// Получаю данныеn = recvfrom(s,buf,mtu,0, (struct sockaddr *)&from, &from_len);
// .... Полученные данные лежат в buf. Дальше они обрабатываются
// .... функцией Netflow_Wrapper, которая принимает (void *), тобиж
// .... я передаю нужные параметры запакованными в структуру "p".// Запускаю поток, и указываю какую функцию выполнить.
pthread_create(&tid, NULL, &Netflow_Wrapper, (void *)&p);
}
Когда смотрю top, да - действительно thread'ов стало 6, и всё работает. Но вот как понять, распараллеливается ли обработка данных на два проца?
>Пишу прожку коллектор пакетов NetFlow. Она через открытый UDP сокет принимает пакеты
>и я попробывал добавить в неё многопоточность. На самом деле мне
>нужно, чтобы использовались для обработки полученных данных ресурсы параллельно двух процов.
>
>
>Сделано это такой конструкией:
>
>--------------------------------------------------------------------
>struct sockaddr_in from;
>socklen_t from_len;
>int mtu;
>char *buf;
>int s;
>
>// Тут начинаю бесконечный цикл для ожидания поступивших пакетов
>// Сокет был открыт ранее
>
>while(1)
>{
> // Получаю данные
>
> n = recvfrom(s,buf,mtu,0, (struct sockaddr *)&from, &from_len);
>
> // .... Полученные данные лежат в buf. Дальше они
>обрабатываются
> // .... функцией Netflow_Wrapper, которая принимает (void *), тобиж
>
> // .... я передаю нужные параметры запакованными в структуру
>"p".
>
> // Запускаю поток, и указываю какую функцию выполнить.
>
> pthread_create(&tid, NULL, &Netflow_Wrapper, (void *)&p);
>
>}
>
>Когда смотрю top, да - действительно thread'ов стало 6, и всё работает.
>Но вот как понять, распараллеливается ли обработка данных на два проца?
>Это работа планировщика. Если он посчитает нужным распаралелить - то это сделает. Дело в том, что Ваши процессы - жрущие I/O, обычно они низкоприоритетные. Нет смылса копировать процесс на другой процессор. В данном случае будет проигрыш.
И то верно. Скажите, Niam, тогда вообще есть смысл в thread'ax обрабатывать полученные из сокета данные как в моём случае? Или это тоже обеспечивается самой системой?
>И то верно. Скажите, Niam, тогда вообще есть смысл в thread'ax обрабатывать
>полученные из сокета данные как в моём случае? Или это тоже
>обеспечивается самой системой?Если пакет обрабатывается быстро можно без thread, если медленно, то без thread это может привести к потери пакетов. Однако и с thread могут быть потери если производительность хоста не достаточная, или обработка ну очень медленная.
>На самом деле мне нужно, чтобы использовались для обработки полученных данных
> ресурсы параллельно двух процов.А насколько тесно связаны между собой данными обработчики? Т.е. стоит ли использовать потоки, а не процессы?
>>На самом деле мне нужно, чтобы использовались для обработки полученных данных
>> ресурсы параллельно двух процов.
>
>А насколько тесно связаны между собой данными обработчики? Т.е. стоит ли использовать
>потоки, а не процессы?
Все зависит от ОС. В Linux потоки и процессы практически одно и тоже. Но процессы более легкие в некоторых случаях, и ими легче управлять, так как у них одно адресное пространство.Можете поиграться с poll/select, но потоки можно использовать, как уже говорилось ранее для ускорения реакции сервера на запросы.
Можете принимать данные в одно потоке, обрабатывать - в разных. Это тоже интересный вариант.Все зависит от сложности операций.
я бы не стал на каждый пакет запускать тред
а завёл бы очередь пакетов,
повесил бы N тредов ждать (pthread_cond_wait) прибытия пакетов эту общюю очередь
из которой они бы разбирали по одному (естественно с необходимой синхронизацией)
Цитата:
Недостатки пользовательских потоков:большинство системных вызовов является блокирующими и ядро блокирует процессы - включая все потоки в пределах процесса;
ядро может направлять на процессоры только процессы - два потока в пределах одного и того же процесса не могут выполняться одновременно на двух разных процессорах.
....
Основной библиотекой для реализации пользовательских потоков является библиотека потоков POSIX, которая называется pthreads...Статья http://www.opennet.me/docs/RUS/linux_parallel/node45.html
>Цитата:
>Недостатки пользовательских потоков:
>
>большинство системных вызовов является блокирующими и ядро блокирует процессы - включая все
>потоки в пределах процесса;
>ядро может направлять на процессоры только процессы - два потока в пределах
>одного и того же процесса не могут выполняться одновременно на двух
>разных процессорах.
>....~90% - полная чушь
~10% - верно только для Linux Threads (2.4 + древние libc)
хотелось бы ссылку на первоисточник