Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сокеты и многопоточность

20K
18 августа 2008 года
Steps09
16 / / 19.07.2007
1) Есть ли в С++ фунция, которая сообщает количество необработаных байт в сокете (байты которые ещё не получены функцыей recv() ).

2) Оптимально ли создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет?
288
18 августа 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Steps09
1) Есть ли в С++ фунция, которая сообщает количество необработаных байт в сокете (байты которые ещё не получены функцыей recv() ).



recv с флагом MSG_PEEK. Еще есть функция select, но с помощью этой функции по-моему можно узнать есть ли на принимающем сокете данные в принципе, но не их кол-во. Подробности в MSDN.

15K
18 августа 2008 года
like-nix
46 / / 27.06.2007
>1) Есть ли в С++ фунция, которая сообщает количество необработаных байт в сокете (байты которые ещё не получены функцыей recv() ).

UNIX разработка сетевых приложений./У. Стивене. — СПб.: Питер, 2003.
13.7. Сколько данных находится в очереди? стр 408

>2) Оптимально ли создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет?

Об этом в этой книге тоже есть глава 23. В кратце рекомендуется пользоваться библиотекой pthread, так как затраты памяти меньше, и межпотоковая передача данных лучше организована. В книге есть примеры как это сделать.
502
18 августа 2008 года
Jail
550 / / 30.01.2007
[quote=like-nix]>1) Есть ли в С++ фунция, которая сообщает количество необработаных байт в сокете (байты которые ещё не получены функцыей recv() ).

UNIX разработка сетевых приложений./У. Стивене. — СПб.: Питер, 2003.
13.7. Сколько данных находится в очереди? стр 408

>2) Оптимально ли создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет?

Об этом в этой книге тоже есть глава 23. В кратце рекомендуется пользоваться библиотекой pthread, так как затраты памяти меньше, и межпотоковая передача данных лучше организована. В книге есть примеры как это сделать.[/quote]
А разве автор написал где-то что у него *nix ОС?
[quote=Steps09]1) Есть ли в С++ фунция, которая сообщает количество необработаных байт в сокете (байты которые ещё не получены функцыей recv() ).[/quote]
Любая функция Си может быть использована в С++. Надеюсь Америку тут не открыл? Возможно Вас интересует какая-то конкретная библиотека? или же Вы можете создать хоть свою собственную функцию на напримере библиотечной.
[quote=Steps09]2) Оптимально ли создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет?
[/quote]
Тут нужно не теоретизировать, а больше практиковать. Вопрос в том, будут ли сообщаться между собой потоки и не выльется ли синхронизации между потоками и борьба за ресурсы в большую проблему для вас, а то и геморой... И не станет ли скорость работы определяющим фактором для вас.
Можно повысить скорость работы приложения с помощью средств параллелизации, типа OpenMP ->
http://openmp.org/wp/
http://ru.wikipedia.org/wiki/OpenMP
или же OpenMPI ->
http://www.open-mpi.org/
OpenMP - просто, быстро, почти без гемора, включение разного рода аннотаций в коде.
OpenMPI - разработка сложна и т.д. и т.п. Зато функций и преимуществ поболее.
Корече говоря, нужно просто пробовать, постепенно наращивая колличесво потоков.
341
19 августа 2008 года
Der Meister
874 / / 21.12.2007
Цитата:
Оптимально ли создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет?

Если ты под виндами, то готов поспорить, что у тебя и без этого на машине их уже более трёхсот (загляни во вкладку "быстродействие" в диспетчере задач). Меня скорость устраивает, а тебя?

Цитата:
Можно повысить скорость работы приложения с помощью средств параллелизации, типа OpenMP или же OpenMPI

Вообще-то, OpenMP и MPI - две большие разницы. OpenMP работает по модели с общей памятью, MPI - с распределённой, путём обмена сообщениями (MPI = Message Passing Interface). Параллелизм OpenMP, в зависимости от реализации, основан на создании потоков и нитей (fibers, легковесных потоков). Единица параллельного выполнения в MPI - процесс. Иными словами, MPI (мне, кстати, больше понравился MPICH) имеет смысл использовать лишь в распределённых и кластерных системах, в то время как OpenMP, в данном случае, малополезна: концепция последовательно-параллельных секций, если "создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет", работать и поддерживаться будет плохо. Если же речь идёт о Windows, то преимущества её использования в большом проекте выглядят ещё более сомнительно.

502
19 августа 2008 года
Jail
550 / / 30.01.2007
[quote=Der Meister]Вообще-то, OpenMP и MPI - две большие разницы. OpenMP работает по модели с общей памятью, MPI - с распределённой, путём обмена сообщениями (MPI = Message Passing Interface). Параллелизм OpenMP, в зависимости от реализации, основан на создании потоков и нитей (fibers, легковесных потоков). Единица параллельного выполнения в MPI - процесс. Иными словами, MPI (мне, кстати, больше понравился MPICH) имеет смысл использовать лишь в распределённых и кластерных системах, в то время как OpenMP, в данном случае, малополезна: концепция последовательно-параллельных секций, если "создавать 200-300 потоков в одном приложении, каждый из которых будет обрабатывать свой сокет", работать и поддерживаться будет плохо. Если же речь идёт о Windows, то преимущества её использования в большом проекте выглядят ещё более сомнительно.[/quote]
Прекрасная выдержка из учебников. Всю эту теорию я сам прекрасно знаю, мог и не стараться так расписывать :) Насчет OpenMP - никогда не пробовал; товарищи советовали. Насчет OpenMPI - похоже ты его никогда не пробовал или мало с ним работал. Скажи мне пожалуйста, а что же тебе мешает использовать этот "fraimework" в локальных задачах одной программы, не кластеров и не распред. сетей??? У меня это почему-то получается... и у developer'ов Sun Solaris это прекрасно получается....видимо что-то мы тут упустили, вот незадача то.
Средства параллелизации в Windows вообще сомнительны, как и латентность нитей в этой ОС.
341
19 августа 2008 года
Der Meister
874 / / 21.12.2007
Цитата:
Насчет OpenMPI - похоже ты его никогда не пробовал или мало с ним работал.

Почти три года своей жизни посвятил связке OpenMP + MPI + Intel C++ Compiler. Больше и под страхом пыток не сяду.

Цитата:
Скажи мне пожалуйста, а что же тебе мешает использовать этот "fraimework" в локальных задачах одной программы, не кластеров и не распред. сетей???

Вкратце, применительно к данной задаче, описать свой framework сможешь? Пусть, например, борьба между потоками (и, соответственно, клиентами) ведётся за консольный вывод.

Цитата:
Средства параллелизации в Windows вообще сомнительны, как и латентность нитей в этой ОС.

Ты просто не умеешь их готовить :)

502
19 августа 2008 года
Jail
550 / / 30.01.2007
[QUOTE=Der Meister]Вкратце, применительно к данной задаче, описать свой framework сможешь? Пусть, например, борьба между потоками (и, соответственно, клиентами) ведётся за консольный вывод.[/QUOTE]
Ну например возмем самую простенькую функцию:
Код:
#include <stdio.h>
#include "mpi.h"

main(int argc, char** argv) {

  int my_rank; /* Ранг процесса */
  int p; /* Количество процессов */
  int source; /* Ранг посылающего */
  int dest; /* Ранг принимающего */
  int tag = 50; /* Тэг сообщений */
  char message[100]; /* Память для сообщения */
  MPI_Status status; /* Статус возврата */

  MPI_Init(&argc, &argv);

  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

  MPI_Comm_size(MPI_COMM_WORLD, &p);

  if (my_rank != 0) {
     sprintf(message, "Привет из процесса %d!", my_rank);
     dest = 0;
     /* Используется strlen(message)+1
       чтобы включить '\0' */
     MPI_Send(message, strlen(message)+1,
       MPI_CHAR, dest, tag, MPI_COMM_WORLD);

  } else { /* my_rank == 0 */

     for (source = 1; source < p; source++) {
     MPI_Recv(message, 100, MPI_CHAR, source, tag,
        MPI_COMM_WORLD, &status);
     printf("%s\n", message);
     }
  }

  MPI-Finalize();

} /* main */

bash-3.2$ mpirun -np 4 mpi_helloworld

далее понятно что произойдет. Эта функция породит 4 потока срествами MPI. Этот "шаблон" функции, можно к примеру использовать в привычном коде, в качестве функции с которой начинается выполнение какого-либо из потоков (остается только реализовать собственный вариант функции "MPI"). А затем - привычное управление борьбой за ресурсы - семафоры, переменнные состояния,мьютексы и т.д. Средствами MPI можно добиться уменьшения времени выполнения задания в привычном потоке.
Можно также реализовать (к примеру) трапецидальную сортировку средствами MPI:
Код:
#include <stdio.h>
#include "mpi.h"

float f(float x) {
  float return_val;
  /* Вычисляет f(x).
    Возвращает результат в return_val. */
  . . .
  return return_val;
}

float Trap(float local_a, float local_b, int local_n,
      float h) {
  float integral; /* Результат вычислений */
  float x;
  int i;

  integral = (f(local_a) + f(local_b))/2.0;
  x = local_a;
  for (i = 1; i <= local-n-1; i++) {
    x += h;
    integral += f(x);
  }
  integral *= h;
  return integral;
} /* Trap */

main(int argc, char** argv) {
  int my_rank; /* Ранг процесса */
  int p; /* Количество процессов */
  float a = 0.0; /* Левая граница */
  float b = 1.0; /* Правая граница */
  int n = 1024; /* Количество трапеций */
  float h; /* Ширина трапеции */
  float local_a; /* Левая граница для процесса */
  float local_b; /* Правая граница для процесса */
  int local_n; /* Количество вычисляемых трапеций */
  float integral; /* Значение интеграла по интервалу */
  float total; /* Общий интеграл */
  int source; /* Процесс, посылающий интеграл */
  int dest = 0; /* Пункт назначения процесс 0 */
  int tag = 50;
  MPI_Status status;

  MPI_Init(&argc, &argv);
  /* Определить ранг процесса */
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  /* Определить количество процессов */
  MPI_Comm_size(MPI_COMM_WORLD, &p);
  h = (b-a)/n; /* h одинаково для всех процессов */
  local_n = n/p; /* Получить количество трапеций */
  /* Вычислить границы интервала и частный интеграл*/
  local_a = a + my_rank*local_n*h;
  local_b = local_a + local_n*h;
  integral = Trap(local_a, local_b, local_n, h);

  /* Суммировать все интегралы */
  if (my_rank == 0) {
    total = integral;
    for (source = 1; source < p; source++) {
       MPI_Recv(&integral, 1, MPI_FLOAT,
           source, tag, MPI_COMM_WORLD, &status);
       total += integral;
    }
  } else {
       MPI_Send(&integral, 1, MPI_FLOAT, dest,
          tag, MPI_COMM_WORLD);
  }

  /* Вывод результата */
  if (my_rank == 0) {
    printf("C n = %d трапециями, оценка\n", n);
    printf("интеграла от %f до %f = %f`\n",
           a, b, total);
  }

  /* Завершить приложение MPI */
  MPI_Finalize();
} /* main */

или же (тоже к примеру) реализовать обмен сообщениями:
Код:
void Get_data(int my_rank, int p, float* a_ptr,
         float* b_ptr, int* n_ptr)
    {
      int source = 0; /* Локальные переменные */
      int dest; /* используемые MPI_Send и MPI_Recv */
      int tag;
      MPI_Status status;
 
      if (my_rank == 0) {
         printf("Введите a, b, и n\n");
         scanf("%f %f %d", a_ptr, b_ptr, n_ptr);
         for (dest = 1; dest < p; dest++) {
            tag = 30;
            MPI_Send(a_ptr, 1, MPI_FLOAT, dest, tag,
                MPI_COMM_WORLD);
            tag = 31;
            MPI_Send(b_ptr, 1, MPI_FLOAT, dest, tag,
                MPI_COMM_WORLD);
            tag = 32;
            MPI_Send(n_ptr, 1, MPI_INT, dest, tag,
                MPI_COMM_WORLD);
         }
      } else {
         tag = 30;
         MPI_Recv(a_ptr, 1, MPI_FLOAT, source, tag,
             MPI_COMM_WORLD, &status);
         tag = 31;
         MPI_Recv(b_ptr, 1, MPI_FLOAT, source, tag,
            MPI_COMM_WORLD, &status);
         tag = 32;
         MPI_Recv(n_ptr, 1, MPI_INT, source, tag,
            MPI_COMM_WORLD, &status);
      }
    }/* Get_data */

[QUOTE=Der Meister ]Больше и под страхом пыток не сяду.[/QUOTE]
Я с тобой согласен, MPI очень сложная штука, но насчет OpenMP говорили что все прям просто как раз, два, три.....:)
[QUOTE=Der Meister]Ты просто не умеешь их готовить :)[/QUOTE]
Дак и не собирался. Пишу немного под другую платформу.
Что-то отдалилсь от темы...
63
19 августа 2008 года
Zorkus
2.6K / / 04.11.2006
А собственно о чем тут можно говорить? Раз автор не соизволил хотя бы вкратце изложить, что ему нужно на бизнес-уровне? С чего все взяли, что автору нужно что-то кластерное? :) Может он просто собрался растопырить 300 портов, и слушать их для организации чата..или что-то в этом роде.
502
19 августа 2008 года
Jail
550 / / 30.01.2007
Цитата: Zorkus
А собственно о чем тут можно говорить? Раз автор не соизволил хотя бы вкратце изложить, что ему нужно на бизнес-уровне? С чего все взяли, что автору нужно что-то кластерное? :) Может он просто собрался растопырить 300 портов, и слушать их для организации чата..или что-то в этом роде.


Мда....а про автора то мы и забыли, кинувшись в дебаты :D

341
19 августа 2008 года
Der Meister
874 / / 21.12.2007
[QUOTE=Zorkus] С чего все взяли, что автору нужно что-то кластерное?[/QUOTE]Чёт я тоже не понял, для чего Jail привёл тут
1) Код, в котором три процесса посылают текст четвёртому
2) Код вычисления интеграла методом трапеций (опять же, разными процессами)
3) Код, в котором процессам рассылается по три числа с плавающей запятой
Кстати, во всех случаях, гораздо проще использовать коллективные операции. Ещё не понял [QUOTE=Jail]Средствами MPI можно добиться уменьшения времени выполнения задания в привычном потоке.[/QUOTE]То есть? В приведённом коде, вместо межпотокового взаимодействия, мы получаем уже межпроцессное, т. е. единсвенный способ получить доступ к ресурсу - прогнать данные как минимум по трубе (pipe). Как, при таком подходе, можно уменьшить время выполнения? К тому же, процесс - это уже слижком накладно.
В приведённых же примерах, использование MPI вполне обосновано, если речь идёт о распределённых вычислениях. Но я-то просил описать кусочек модели для[QUOTE=Zorkus]...растопырить 300 портов, и слушать их для организации чата..или что-то в этом роде.[/QUOTE], реализованный средствами MPI. Без кода, так гораздо проще.
Промимо всего прочего, приведённые куски кода совсем не используют потенциал MPI. Места, гда появляются MPI_Send/MPI_Recv, всегда читаются сложно, и их очень сложно отлаживать.
Кстати, по поводу OpenMP. Нередко (мягко сказал) тот же Intel C++ Compiler for Linux лучше распараллеливает вычисления без неё, чем с ней.
20K
20 августа 2008 года
Steps09
16 / / 19.07.2007
Дам, а я уже думал, что уже не увижу ни одного поста в этой теме.

Относительно первого, то мне подходит MSG_PEEK, просто во время первого прочтения МСДНа я подумал, что он отличается от простого вызова gets(), тем что не убирает данные из входящего буфера (не знаю в каком состоянии я это читал, но что-то не заладилось у меня с его инфой).

Относительно потоков, то меня интересовало не слишком ли они дадут нагрузку на дескриптор процеса (никогда не работал с ними, но в данном случае это наверно оптимальное решение).

Относительно ОС, то обе.

Относительно 300 портов, то это слишком, мне и одного хватит.

Каждый сокет расчитан на р2р общение.

Qt я на данный момент использовать не буду (пока не подойду к GUI), а поточность и сокеты для обеих ОС на данной стадии мне будет легче реализовать без него.
63
20 августа 2008 года
Zorkus
2.6K / / 04.11.2006
Твое сообщение мало прояснило тему.
Цитата:
Относительно потоков, то меня интересовало не слишком ли они дадут нагрузку на дескриптор процесса (никогда не работал с ними, но в данном случае это наверно оптимальное решение).


Это нужно экспериментировать и потом так же много и вдумчиво анализировать результаты.

20K
20 августа 2008 года
Steps09
16 / / 19.07.2007
Цитата: Zorkus
Твоё сообщение мало прояснило тему.



Я собираюсь написать битторрент клиент.

Вот на что будут тратится основные потоки и сокеты:
- по одному потоку и сокету на трекер
- по одному потоку и сокету на сида/лича (подключённого)
- один поток и сокет для прослушки входящих подключений.
- поток на менеджера подключений

Борьбы за ресурсы как таковой почти не будет.

Основными фронтами будут
- между трекерными потоками и потоком менеджера (легко организовывается с помощю критических секцый)
- между самими р2р подключениями за доступ к файлам (теми же секцыями)

Если видите явные недостатки, то скажите.

46K
22 декабря 2008 года
ilmarranen
3 / / 22.12.2008
Дайте плиз рабочий пример клиента и сервера, один из которых отсылает сообщение с некоторыми данными, другой получает. По локальной, например, сети.

Не могу найти примеров для кластерных систем, а не многопроцессорных. Такое впечатление, что это знает каждый ребенок, но никто нигде не подумал об этом написать. Везде только локальное взаимодействие процессов.
46K
22 декабря 2008 года
ilmarranen
3 / / 22.12.2008
Речь идёт об использовании MPI
341
23 декабря 2008 года
Der Meister
874 / / 21.12.2007
Цитата: ilmarranen
Речь идёт об использовании MPI


Книжек - вагон.

Шпаковский, Серикова - Программирование многопроцессорных систем в стандарте MPI.pdf
Антонов - параллельное программирование с использованием стандарта MPI.pdf
bukatov_progr_multiprocessors.pdf

341
23 декабря 2008 года
Der Meister
874 / / 21.12.2007
И, кстати, чем для старта не подходят примеры Jail?
46K
24 декабря 2008 года
ilmarranen
3 / / 22.12.2008
Речь идёт не чтоль о параллельном, сколько о распределенном программировании... Насколько я понял, в примерах Jail речь о первом - локальная многопроцессорная система...

Но за книжки спасибо. :)
341
25 декабря 2008 года
Der Meister
874 / / 21.12.2007
[QUOTE=ilmarranen]Насколько я понял, в примерах Jail речь о первом - локальная многопроцессорная система...[/QUOTE]Ничего подобного. Как захотите, так и будет работать: распределением приложения занимается mpiexec/mpirun, в том-то и оно. Для того, чтобы развернуть кластер MPI, вам нужно всего лишь поставить MPICH (или OMPI) на его узлы.
Примеры кода будут лишены смысла до тех пор, пока вы не поймёте саму философию MPI. Поэтому я насоветовал вам книжек.
Там ещё есть коллективные операции и топологии вычислений, понять которые тоже желательно.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог