Ответы пользователя по тегу Многопоточность
  • Алгоритм многопоточности?

    @nirvimel
    Не надо создавать отдельный поток для каждого файла. Создайте два пула потоков.

    Пул №1 (вычислительный): количество потоков равно количеству ядер CPU. Во входную очередь сыплются блоки данных, для которых потоки пула рассчитывают хеши.

    Пул №2 (синхронное чтение с диска): количество потоков равно количеству ядер, помноженному на некоторую константу (в исходниках разных библиотек я видел значения от 2 до 10). Во входную очередь сыплются имена файлов, которые потоки пула открывают, читают и засылают прочитанные блоки во входную очередь пула №1.
    Примечание: расход памяти регулируется ограничением максимальной длинны входной очереди пула № 1. Практически получается, что пул №1 ограничивает нагрузку на пул №2, который в норме недонагружен.

    Отдельный поток, который совершает обход дерева каталогов и засылает найденные имена файлов во входную очередь пула №2. Длину этой очереди, тоже можно ограничить, но не так жестко (я бы задал размер в несколько сотен).

    P.S.: Все очереди с ограничением длины должны быть, конечно же, с блокировками (не lock-free), так как через них происходит регулировка нагрузки (иначе все потоки нагрузятся на 100%).
    Размер блоков данных, поступающих на вход пула №1 не надо делать слишком маленьким (я бы задал 64 килобайта, например).
    Ответ написан
    Комментировать
  • Как реализовать блокировку ресурса для всех потоков, кроме одного (еще раз)?

    @nirvimel
    Для этого удобно использовать очередь queue (howto).
    1. Изначально в очередь загоняются (put) все доступные токены.
    2. Каждый поток получает (get) один свободный токен из очереди (предварительно ожидает пока он там появятся).
    3. Как только токен освобождается, он кладется (put) обратно в очередь и его моментально подхватывает один из ожидающих потоков.

    Схема будет отлично работать и не вызывать коллизий при количестве потоков многократно превосходящем количество токенов, но только если токены захватываются на непродолжительное время и быстро освобождаются, иначе большая часть потоков будут вечно висеть в ожидании свободных токенов.
    Ответ написан
    5 комментариев
  • Как поубивать потоки которые я сам же и насоздавал?

    @nirvimel
    В цикле проверяется флаг (условие выхода), изначально заданный в False, но сбрасываемый в True обработчиком команды /kill. Удобно использовать dict для соотнесения отдельным потокам флагов выхода.
    Ответ написан
  • Как считать сериализованные объекты из в файла в ArrayList из этих самых объектов?

    @nirvimel
    Читать объекты в бесконечном цикле до тех пор, пока не вылетит EOFException.
    Ответ написан
    Комментировать
  • Обработка потоков на сервере мессенджера?

    @nirvimel
    Количество потоков не равно количеству открытых сокетов. Расходовать на каждое подключение отдельный поток ни в коем случае нельзя. Но синхронно закрывать сокет после обработки подключения совсем не обязательно. Сокет - просто значение ячейки массива (или карты) будет взято и использовано когда понадобится в любом потоке (работа с конкретным сокетом, конечно, должна быть обернута в соответствующий синхроблок). Единственно, о чем не следует забывать это - KeepAlive пинги (отдельный пул потоков и таймера под них, например), которые обеспечивают сразу две задачи: 1) помогают удержать неактивное соединение (умные роутеры любят закрывать "мертвые" соединения, и клиент, в зависимости от реализации, может делать то же). 2) очищают список сокетов от реально мертвых.
    Ответ написан
    2 комментария
  • Выбор языка для многопоточного приложения под linux?

    @nirvimel
    C - Плюсы: Возможность выжать максимальную скорость из железа.
    Минусы: При переходе с динамических скриптов (типа, упомянутого в вопросе, PHP) может несколько шокировать своей многословностью и необходимостью явно описывать каждую мелочь, которая в других языках выводится неявно.
    Java - Плюсы: Автоматическая сборка мусора сильно облегчает жизнь и смягчает шок при переходе с динамических скриптов. Гениальный JIT - позволяет сократить отставание от голого железа в скорости (в лучшем случае) до 30%-50% (по сравнению с отставанием в разы и десятки раз для динамических скриптов).
    Минусы: Чтобы воспользоваться всей мощью JIT, требуется глубокое понимание принципов его работы и отказ от использования объектов (основной фишки Java) в глубине самых нагруженных циклов.
    C++ - Разные люди по-разному используют его. Кто-то на нем пишет в стиле C, получает быстродействие чистого C и презрение истинных C++совцев. Кто-то на нем пишет в стиле Java и получает более компактный код, но и быстродействие как у Java. На самом деле на этом языке можно писать красивые, элегантные и не уступающие в быстродействии программы, но на это уйдут годы обучения (речь не о синтаксисе языка и не о стандартной библиотеке).
    Ответ написан
    3 комментария
  • Как перезапустить один поток в консоли?

    @nirvimel
    Какие инструменты вы имеете в виду? Снаружи невозможно повлиять на ход выполнения программы. Обработка исключительных ситуаций должна быть предусмотрена в коде. Обычно для этого реализуют что-то типа планировщика (scheduler) в отдельном потоке, который регулярно опрашивает рабочие потоки потоки (worker) и если worker не успел ответить на запрос в течении определенного времени, он убивается и перезапускается. Общение между потоками идет через очереди ConcurrentLinkedQueue (иногда BlockingQueue, но обычно они используются не для опроса, а для пересылки потоков данных). worker в цикле опрашивает входящую очередь и отвечает на пинг через исходящую. Также неплохо завернуть весь worker в обработчик RuntimeException, в котором сигнализировать scheduler о произошедшим.
    Ответ написан
    3 комментария
  • Многопоточное программирвоание java, существуют ли книги?

    @nirvimel
    Многопоточность неплохо рассмотрена у Брюса Эккеля, например.
    Если интересует средства стандартной библиотеки (классический подход к многопоточности) - то 100 страниц вполне достаточно, я считаю.
    Если интересуют альтернативные подходы, типа акторов, promise/future и stm, то для этого существую отдельные библиотеки. У каждой библиотеки есть своя документация, книги также пишутся по конкретным библиотекам, при этом не говорят словами "многопоточность под java", а называют конкретную библиотеку.

    Еще один сравнительный обзор различных книг по многопоточности в java. Но лично я не читал ни одной из них, простое чтение исходников стандартной библиотеки (прекрасно документированной) плюс обще пониманием архитектуры аппаратной платформы и виртуальной машины, дает наилучший результат на практике.
    Ответ написан
    Комментировать
  • Как получить данные из потоков обратно в main в java?

    @nirvimel
    Для этого существует очередь LinkedBlockingQueue.
    Потоки пишут в нее возвращаемые значения, промаркированные id задания.
    main читает из нее и восстанавливает массив возвращаемых значений по их id, не опираясь на порядок элементов в очереди, который ничем не гарантирован.
    Ответ написан
    Комментировать
  • Как организовать параллельную работу по сети с несколькими устройствами?

    @nirvimel
    1. Подобные сервера лучше писать не на потоках threading (которые все равно упираются в GIL), а на "зеленых" потоках, например gevent, который создан для решения задач, подобной вашей, с максимальной производительностью.
    2. Проблему зависания потоков в вечном ожидании решает настройка keepalive: клиент обязуется передавать пустые пакеты раз в n секунд, если ему больше нечего передавать. А сервер делает socket.settimeout(n+10) и при вызове recv отлавливает исключение socket.timeout, которое сигнализирует, что клиент "отвалился".
    Ответ написан
    Комментировать
  • Почему у меня не срабатывает метод join() в потоке?

    @nirvimel
    Вы просто пишите переменную Y3 в потоке thread3 и просто читаете ее в потоке thread1 - это и есть ошибка.

    Прочитайте что-нибудь про Java concurrency и параллельные вычисления в целом - это довольно сложные темы, и сложность тут, конечно, не в том чтобы навызывать много new Thread().

    Возможно в вашем случае проще будет построить логику на модели акторов (на java много разных реализаций, хотя на scala это сделано красивее). Если изучить многопоточность с нуля, то это будет проще в изучении и перспективнее в применении, чем классические подходы.
    Ответ написан
    4 комментария
  • Почему создаются дополнительные потоки в конце очереди?

    @nirvimel
    С виду тут все в полном порядке.
    Имеем 50 ПАРАЛЛЕЛЬНЫХ потоков, которые питаются из очереди в 500 элементов.
    1. К моменту когда первый поток окончил выполнение своего задания, на выполнение которого потратил некоторое время, в очереди давно уже осталось 450 элементов, ведь расхватывают новые задания потоки мгновенно и ПАРАЛЛЕЛЬНО.
    2. К моменту, когда завершилось выполнение 450-го задания, оставшиеся 50 уже находятся в работе, их уже расхватали потоки, и в очереди осталось 0 элементов. После чего оставшиеся 49 потоков заканчивают выполнение своих заданий и каждый рапортует о том, что наблюдает в очереди ноль элементов, после чего воркеры вылетают по task_done() и подбираются join-ом в основном потоке.
    Ответ написан
    2 комментария