Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux C++ потоки / 25 сообщений из 69, страница 1 из 3
22.06.2016, 15:27
    #39260442
arias
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Доброго времени суток, у меня следующая проблема. У меня есть список типа vector<string>, в котором приблизительно 25 000 строк, суть программы в следующем, нужно в потоках обработать данные строки(строка представляет собой домен для последующего получения ip адресов), как можно быстрее. На данный момент, программа ругается в тот момент, как вызывается первый экземпляр объекта потока, а именно в следующем строке: pthread_join(threads[0], NULL); , дальше не идет программа, в чем может быть проблема? Вот ошибка: dpi kernel: [ 3366.211960] dpi[11554]: segfault at 4 ip b76dc056 sp bf809700 error 6 in libpthread-2.19.so[b76d6000+18000]
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
void* threadFunc(void* thread_data)  {
  string domain = *(string *)thread_data;
  syslog(LOG_INFO, "Info: domain in = %s", domain.c_str());
  struct hostent *he;
  struct in_addr **addr_list;
  syslog(LOG_INFO, "Info: domain search information");
  if((he = gethostbyname(domain.c_str())) == NULL)
    syslog(LOG_NOTICE, "Notice: Not found IP addresses for host - \"%s\"", domain.c_str());
  else  {
    addr_list = (struct in_addr **)he->h_addr_list;
    for(int j = 0; addr_list[j] != NULL; j++)
      syslog(LOG_INFO, "Info: Found IP address \"%s\" for host - \"%s\"", inet_ntoa(*addr_list[j]), domain.c_str());
  }
  syslog(LOG_INFO, "Info: domain write information");
  pthread_exit(NULL);
  return NULL;
}

int find_ip2(vector<string> domains)  {
  int n = domains.size();
  pthread_t threads[n];

  syslog(LOG_INFO, "Info: count domains = %d", n);

  for(int j = 1, i = 0; j < n ; j++, i++)  {
     syslog(LOG_INFO, "Info: %d. domain = %s", j, domains[j].c_str());
     syslog(LOG_INFO, "Info: %d. count domains = %d", j, n);
     syslog(LOG_INFO, "Info: %d. domain send = %s", j, domains[j].c_str());
     syslog(LOG_INFO, "Info: %d. domain %d -> set = %s", j, (i + 1), domains[j].c_str());
     pthread_create(&threads[i], &tattr, threadFunc, &domains[j]);
  }

  syslog(LOG_INFO, "Info: start clearing thread!");

  for(int t = 0 ; t < n ; t++)  {
    syslog(LOG_INFO, "Info: threads[%d] join(%d joins)!", t, n);
    pthread_join(threads[t], NULL);
  }

  syslog(LOG_INFO, "Info: domain finish search ips.");

  return n;
}
...
Рейтинг: 0 / 0
22.06.2016, 15:39
    #39260474
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
ariasУ меня есть список типа vector<string>, в котором приблизительно 25 000 строк
Это vector<string> domains ?

Попробуй оставить 25 строк. Будет работать?
...
Рейтинг: 0 / 0
22.06.2016, 15:42
    #39260476
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Непонятно где инстнциируется &tattr. Может это необязательно но хотелось-бы чтоб сорс был самодостаточный.
...
Рейтинг: 0 / 0
22.06.2016, 15:51
    #39260490
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
И... не знаю реально-ли стартовать 25 тыщ потоков. Тут по идее должнен быть какой-то диспетчер
типа Круглый-Робин.

А так по коду получается что на каждый домен будет форкнут тред.

И + надо анализировать коды возврата. Возможно там где-то что-то падает.

http://man7.org/linux/man-pages/man3/pthread_create.3.html On success, pthread_create() returns 0; on error, it returns an error
number, and the contents of *thread are undefined.
...
Рейтинг: 0 / 0
22.06.2016, 15:51
    #39260491
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Можешь потоки на std::thread переделать, там синтаксис попроще и приведение типов не требуется.
...
Рейтинг: 0 / 0
22.06.2016, 15:53
    #39260497
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Просто не надо создавать 25000 потоков )))

Переделайте алгоритм, чтобы потоков было достаточное, но небольшое число. Например 2*число CPU.
...
Рейтинг: 0 / 0
22.06.2016, 16:00
    #39260507
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Anatoly Moskovsky, я думаю что для Linux не очень сложно создать 25 тыщ потоков.
Просто ... как-то умеючи надо. Покурить там текущее значение /proc/sys/kernel/threads-max.
Покурить откуда оно ставит дефолт. Возможно там какая-то оценочная формула есть.
От мемори там или от версии ядра.

Но конечно постановка - причудливая. Какой-то DNS сервер....
...
Рейтинг: 0 / 0
22.06.2016, 16:04
    #39260518
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
maytonAnatoly Moskovsky, я думаю что для Linux не очень сложно создать 25 тыщ потоков.
Каждому потоку 1 Мб стэка надо выделить, это 25 Гб адресного пространства. ХЗ выделит ли столько ОС для одного процесса.
...
Рейтинг: 0 / 0
22.06.2016, 16:06
    #39260521
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Dima TmaytonAnatoly Moskovsky, я думаю что для Linux не очень сложно создать 25 тыщ потоков.
Каждому потоку 1 Мб стэка надо выделить, это 25 Гб адресного пространства. ХЗ выделит ли столько ОС для одного процесса.
Мы не знаем какое там выделение. Возможно отложенное. У тебя линухЪ под рукой?
Глянь плиз чему у тебя равна эта переменная.
...
Рейтинг: 0 / 0
22.06.2016, 16:13
    #39260530
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Код: plaintext
1.
2.
...:~# cat /proc/sys/kernel/threads-max
7873
...
Рейтинг: 0 / 0
22.06.2016, 16:16
    #39260535
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Ну... всего-лишь в 4 раза меньше

Кстати чортов homepage Сергея Брина мне подсказывает что размер
стека можно "уплотнить".

Волшебная функция нам в помошь.

Код: plaintext
1.
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
...
Рейтинг: 0 / 0
22.06.2016, 17:29
    #39260615
arias
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
По поводу "&tattr" описался, когда писал сообщение, в реальном коде этого куска уже нет давно.
Вроде установка 20 потоков решило проблему, я пытался экспериментировать с количеством одновременных потоков, хотя сколько примеров не смотрел, нигде не описано максимальное чисто одновременных потоков.
По поводу максимального числа потоков в системе у меня следующий вывод:
Код: plaintext
1.
2.
cat /proc/sys/kernel/threads-max
64523


Всем спасибо, буду дальше разбираться с кодом. Сложно вспоминать C++, после того, как пару лет пришлось писать на PHP.
...
Рейтинг: 0 / 0
22.06.2016, 17:39
    #39260626
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
ariasПо поводу "&tattr" описался, когда писал сообщение, в реальном коде этого куска уже нет давно.
Было-бы очень продуктивно приводить актуальный исходник.
...
Рейтинг: 0 / 0
22.06.2016, 18:11
    #39260663
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
ariasхотя сколько примеров не смотрел, нигде не описано максимальное чисто одновременных потоков.
Одновременно может выполняться столько потоков, сколько логических процов доступно ОС. Где-то их 2 где-то 40 и больше. Если в очереди на исполнение больше, то это только вызовет лишние тормоза из-за переключения потоков.
Потом зависит от того что твои потоки делают, если поток ждет ввод/вывод, то в это время проц может другой поток поработать.
Создание потока тоже не дешевое действие, поэтому обычно делают пул потоков, которые висят и ждут задания, есть задание - обработали, дальше ждут. Как у тебя написано: создать поток ради пары строк кода, это как купить квартиру чтобы разок переночевать.
Почитай какую-нибудь книжку про многопоточность.

Это нездоровая строчка
Код: plaintext
1.
pthread_t threads[n];


в современном С++ это можно, но при больших n будут проблемы, т.к. массив создается на стэке, а стэк всего 1Мб. маленькие массивы можно так делать, а с большими аккуратно, лучше заменить на vector.
...
Рейтинг: 0 / 0
22.06.2016, 18:20
    #39260671
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Дим ты не совсем прав. Твоя формула "логических процов" справедлива для численных методов.
Но ты открой свой собственный диспетчер задач и посмотри сколько процессов и сколько потоков
в каждом (если Windows).
...
Рейтинг: 0 / 0
22.06.2016, 19:05
    #39260697
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
maytonДим ты не совсем прав. Твоя формула "логических процов" справедлива для численных методов.
я формулы не давал, попытался объяснить что универсальной формулы нет, а для конкретного приложения ее надо выводить с учетом особенностей приложения, может не очень понятно написал.
...
Рейтинг: 0 / 0
22.06.2016, 19:16
    #39260705
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Если выкинуть всякий лишний мусор типа логгирования то поток делает 1 единственный
полезный вызов

Код: plaintext
1.
gethostbyname(domain.c_str())



и его архитектуру следует обсуждать.
...
Рейтинг: 0 / 0
22.06.2016, 19:30
    #39260719
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
maytonи его архитектуру следует обсуждать.
Тут обсуждать особо нечего, надо самодельный запрос DNS-серверу. Тут протокол DNS надо поизучать чтоб не слать 25000 UDP пакетов. Вроде по TCP тоже можно. 1 поток.
...
Рейтинг: 0 / 0
22.06.2016, 19:48
    #39260734
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Вики пишет
Протокол DNS использует для работы TCP- или UDP-порт 53 для ответов на запросы.
Традиционно запросы и ответы отправляются в виде одной UDP-датаграммы. TCP используется,
когда размер данных ответа превышает 512 байт, и для AXFR-запросов.

Да тут надо раскурить особенности протокола и подстроить под него софт. Тоесть не DDOS-ить
бедного провайдера а настроить некую номинальную скорость при которой нет шейпинга
и авто-ограничителей. Я-бы еще обратил внимание на возможные дубли доменов.

Кстати используя свойство распределённости DNS, запросы можно слать во много направлений
пока хватает сетевого канала. Это КМК более благоприятный путь оптимизации.
...
Рейтинг: 0 / 0
22.06.2016, 20:07
    #39260748
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
ИМХУ не тот случай. Слать на ближайший. 25000 запросов это не много, не DDoS. Чуть нагрузят сервер, но максимум за секунду на все ответит.
...
Рейтинг: 0 / 0
22.06.2016, 20:56
    #39260775
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
25 тысяч пакетов.... вобе стороны.
...
Рейтинг: 0 / 0
22.06.2016, 21:06
    #39260782
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
Можно попробовать поднять локальный DNS, и спрашивать у него.
...
Рейтинг: 0 / 0
22.06.2016, 22:46
    #39260825
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
maytonне очень сложно создать 25 тыщ потоков
Шею себе сломать тоже не сложно, и что? )))
...
Рейтинг: 0 / 0
22.06.2016, 22:54
    #39260830
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
mayton25 тысяч пакетов.... вобе стороны.
Чтобы обрабатывать 100К пакетов объемом 1Гбит в секунду хватает недорогого 4 ядерного проца.
...
Рейтинг: 0 / 0
23.06.2016, 00:05
    #39260850
Shaman_Ist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux C++ потоки
ТС уже "отвалился", но, никто из отвечающих, не выспросил у него: "а на фейхуа" ему собирать DNS-info многопорочно :).
Получение информации ограничено скоростью канала. И наплевать на то, сколько потоков (процессов) стучится в него с запросами . Ибо создание и запуск процессов в Linux ныне (на современных процессорах) заведомо быстрее ответов от DNS сервера. Получается от кучи процессов профита нет, а ОЗУ кушаем. И то, если настройки ядра ОС позволят столько процессов (потоков) создать и, соответственно, запустить.
Функция gethostbyname( как, справедливо заметил mayton, единственно payload в приведенном фрагменте кода), помнится, синхронная? Еще минус в копилку "кучи процессов", опять же из-за памяти.
А поднятие локального DNS не очень-то похоже на здравый совет, ибо задача, обрисованная ТС, оченно похожа на "кеширующий DNS на этапе построения таблицы".
В итоге: неизвестно, чего хотел ТС, но советы от Dima_T, mayton довольно во многом применимы. Сказанное Анатолием (Anatoly Moskovsky) может и должно (но не все) быть принято к сведению.
Засим откланиваюсь, ибо не совсем трезв.
Поздравьте нас (я, сестра и зять) с рождением нового Тамерлана ;).
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux C++ потоки / 25 сообщений из 69, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]