powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux C++ потоки
25 сообщений из 69, страница 1 из 3
Linux C++ потоки
    #39260442
arias
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток, у меня следующая проблема. У меня есть список типа 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
Linux C++ потоки
    #39260474
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ariasУ меня есть список типа vector<string>, в котором приблизительно 25 000 строк
Это vector<string> domains ?

Попробуй оставить 25 строк. Будет работать?
...
Рейтинг: 0 / 0
Linux C++ потоки
    #39260476
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Непонятно где инстнциируется &tattr. Может это необязательно но хотелось-бы чтоб сорс был самодостаточный.
...
Рейтинг: 0 / 0
Linux C++ потоки
    #39260490
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И... не знаю реально-ли стартовать 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
Linux C++ потоки
    #39260491
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можешь потоки на std::thread переделать, там синтаксис попроще и приведение типов не требуется.
...
Рейтинг: 0 / 0
Linux C++ потоки
    #39260497
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто не надо создавать 25000 потоков )))

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

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

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

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

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


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

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


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

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



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

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

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


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