Хорошее значение манипулирования потоком

Я написал простую программу, которая реализует схему мастер / работник, где мастер является основным потоком, а рабочие создаются им.

Основной поток записывает что-то в общий буфер, а рабочие потоки читают этот общий буфер, запись и чтение в общий буфер организуются с помощью блокировки чтения / записи.

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

Согласно большому посту на похожую проблему, я обнаружил, что, вероятно, манипулирует приоритетом потока под SCHED_OTHER политика не допускается, что может быть изменено nice только значение

Я написал процедуру, чтобы дать рабочим потокам более низкий приоритет, чем основному потоку, но, похоже, он работает неправильно.

void assignWorkerThreadPriority(pthread_t* worker)
{
    struct sched_param* worker_sched_param = (struct sched_param*)malloc(sizeof(struct sched_param));
    worker_sched_param->sched_priority =0; //any value other than 0 gives error?
    int policy = SCHED_OTHER;
    pthread_setschedparam(*worker, policy, worker_sched_param);
    printf("Result of changing priority is: %d - %s\n", errno, strerror(errno));
}

У меня двоякий вопрос:

  1. Как я могу установить хорошее значение рабочих потоков, чтобы избежать голодания основного потока.
  2. Если это невозможно, то как я могу изменить политику планирования на такую, которая позволяет менять приоритет.

Изменить: мне удалось запустить программу, используя другие политики, такие как SCHED_FIFO все, что мне нужно было сделать, это запустить программу как суперпользователь

1 ответ

Вы не можете избежать проблем, используя блокировку чтения / записи, когда использование чтения и записи очень равномерно. Вам нужен другой метод. Вам нужна очередь сообщений без блокировки или независимые рабочие очереди или один из многих других методов.

Вот другой способ сделать работу, способ, которым я сделал бы это. Работник может убрать буфер и работать с ним, а не хранить его в общем доступе:

  • Напишите тему:
    • Создать рабочий элемент.
    • Заблокируйте мьютекс или CriticalSection, защищая текущую очередь и указатель на очередь.
    • Добавить рабочий элемент в очередь.
    • Отпустите замок.
    • При желании сигнализировать переменную условия или событие. Другим вариантом является проверка рабочих потоков на работу по таймеру.
  • Рабочая нить:
    • Создать новую очередь.
    • Дождитесь условной переменной, события или другого сигнала или дождитесь таймера.
    • Заблокируйте мьютекс или CriticalSection, защищая текущую очередь и указатель на очередь.
    • Установите указатель текущей очереди на новую очередь.
    • Отпустите замок.
    • Перейдите к работе с теперь частной очередью.
    • Удалить очередь, когда все рабочие элементы завершены.
  • Теперь запись потока создает больше рабочих элементов. Когда все рабочие потоки имеют свои собственные копии очереди для работы, она сможет спокойно писать множество элементов.

Вы можете изменить это. Например, рабочий поток может заблокировать очередь и переместить ограниченное количество рабочих элементов в свою собственную внутреннюю очередь вместо того, чтобы забрать все это.

Другие вопросы по тегам