Intereting Posts
C pow () не работает с переменным показателем Как остановить загрузку с задержкой DLL из-за ошибки системы «Отсутствует на вашем компьютере»? Отправка информации с помощью сигнала в Linux читать файл растрового изображения в структуру как повторить строку на языке C Как преобразовать строку в шестнадцатеричное значение в C Возможная утечка памяти Valgrind в OSX El Capitan Политика расписания DEADLINE не найдена В чем разница между спецификаторами формата% ul и% lu C? разница между возвратом 1, возвратом 0 и возвратом -1 и выходом? Переход от линейного зондирования к квадратичному зондированию (хеширование) заполнение динамически выделенного массива строк? точное представление плавающих точек в c Почему я получаю ошибку компилятора: «SIGSUR1» не был объявлен в этой области? Подчините процедуру подclassа, чтобы он мог использоваться как в окне, так и в диалоговом окне

Выполнить функцию при выходе pthread

У меня есть приложение на C ++, в котором я создаю pthreads для запуска предоставляемых пользователем функций. Я хочу быть в состоянии быть предупрежденным каким-то образом, когда stream выходит, так что я могу удалить его из массива pthread, который я использую, чтобы сохранить streamи. Есть ли способ сделать это, или если функция просто установит некоторое «волшебное значение». Поскольку мой основной код, который порождает pthreads, является своего рода runloop, я могу легко проверить условие выхода.


Кроме того, используется перегрузка std::vector для отслеживания моих streamов перегрузки? Количество streamов не обязательно является постоянным, многие streamи или очень немногие могут работать. Или есть еще один контейнер STL, который был бы хорош для этих дополнений и удалений (дополнения всегда на одном конце, удаления практически в любом месте). Есть ли какая-то другая структура для отслеживания pthreads? Будет ли стек или список быть здесь? Или стандартный массив C с большим максимумом? Из-за характера проблемы я мог бы также поддерживать массив фиксированных размеров рабочих streamов, которым я передаю пользовательские функции, которые должны выполняться. Это хорошее решение?

Извините за длинный запутанный вопрос, но я работал только с streamами на динамических языках, где это никогда не будет проблемой.


EDIT (3/08/12): После прочтения ответа @ jojojapan, я решил использовать threadpool. В моей структуре у меня есть один производитель (stream в runloop) и многие потребители (рабочие streamи в пуле). Существует ли структура данных, созданная для многопоточного однопроцессорного многопользовательского использования? Или я просто использую std::queue с pthread_mutex_t на нем?

    1. Один из вариантов, который вы, возможно, захотите рассмотреть, – это не на самом деле завершать и удалять streamи после завершения задачи, а вместо этого сохранять их в живых и ждать, пока им будет назначена новая задача. Вы можете сделать это, выполнив две вещи:

      1. Используйте (почти) бесконечный цикл в streamе
      2. Используйте параллельную очередь или другую технику, которая заставляет их ждать, пока сигнал будет передан другим streamом. Шаблоны проектирования и страtagsи обсуждаются в нескольких вопросах SO, например, этот
    2. Если вы действительно хотите отправить сигнал после окончания streamа, вы можете использовать pthread_cond_t и вызвать pthread_cond_signal на нем непосредственно перед тем, как stream достигнет инструкции return . Конечно, предполагается, что есть еще один stream, который ждет этих сигналов и действует на них, удалив соответствующий stream из вектора. Подробности об использовании описаны на соответствующей странице руководства, но также и в этом сообщении SO .

    Редактировать, связанное с комментарием и отредактированной частью вопроса:

    1. Что касается количества рабочих streamов: это зависит от ресурсов, используемых больше всего по streamам. Если эти streamи выполняются, это в основном вычисления и бит доступа к памяти, другими словами, если они связаны с ЦП, имеет смысл использовать столько streamов, сколько может поддерживать ваш процессор (в частности, имеется определенное количество ядер, и количество (аппаратных) streamов на kernel, которое может выполнять ваш процессор, прежде чем они начнут замедлять друг друга. Нити, которые вы создаете (streamи программного обеспечения), должны быть примерно столько же или, возможно, еще несколько (до двух раз больше аппаратные streamи разумны в соответствии с тем, что здесь говорит @Tudor )). Однако, если ваши streamи сильно используют память (привязанная к памяти) или жесткий диск (IO-привязанный) или другие ресурсы, такие как сеть, NFS или какой-либо другой сервер, вы можете уменьшить количество streamов в порядке ( ) не заставлять их блокировать друг друга и (б) не наносить неоправданно большую нагрузку на определенные ресурсы. Определение правильного количества streamов может быть предметом экспериментов, и сохранение числа настраиваемых обычно является хорошей идеей.

    2. Что касается лучшей структуры данных для хранения рабочих задач: параллельная ограниченная очередь, упомянутая в комментариях сообщения, которое я привел выше, вероятно, очень хорошо. Я сам не пробовал. Но если вы хотите, чтобы все было просто, стандартная std::queue или даже просто std::vector не была бы плохим выбором, если бы вы правильно защищали их с помощью технологии signal / mutex.

    Подумайте об изменении страtagsи целиком и используйте существующую библиотеку threadpool. Они сделают эту работу за вас, вы сэкономите много не очень смешной отладки.

    Пул Boost.thread – одна из многих ссылок .

    Простой способ сделать это – просто использовать трубку.

    Откройте трубку перед тем, как развернуть нити. Передайте трубку fd как часть данных streamа. Прежде чем выйдет stream, запишите его pthread_self() в трубу. На главном конце трубы должна быть основная или отдельная резьба. Он читает stream мертвой нити и сразу делает pthread_join. (Если это отдельная нить, она может просто блокировать чтение канала, если она в основном просто делает ее частью вашего выбора / опроса или что-то еще.)

    Это дает вам гибкость в том, что вы не используете структуру данных для сохранения TID вообще, если не хотите. Если вы хотите сохранить их, то список или карта – лучший выбор, чем вектор.

    Если у вас есть основной запуск streamов и отдельный stream «жатки», который их собирает, и вы хотите сохранить их в некоторой структуре, вам нужно будет синхронизировать доступ к структуре между ними.