2015-08-26 3 views
0

У меня есть сценарий читателей-читателей из/в общий буфер. Все потоки писателей имеют наивысший приоритет, чем поток читателя. Функция активации потока считывателя находится в непрерывном цикле, если в буфере есть какие-либо данные, в которых он считывает все содержимое при съемке и вызывает функцию sche_yield().Занятие процессора показывает 100%

В этом сценарии я ожидал, что загрузка процессора будет где-то от 20 до 30%, но она показывает 100% (верхняя команда Linux), но после того, как вы немного разобрались, я понял, что поток читателей после чтения данных, которые он добавляет в конце очереди планирования и нет писателей для записи данных, считыватель снова запланирован, и он снова дает и добавляется в конце очереди планирования, и это повторяется, и из-за этого CPU показывает 100%.

Я чувствую, что должно быть обработано событие, связанное с обработкой событий, а не с читателем в цикле while, непрерывно записывающим данные. Не могли бы вы помочь в написании обработки событий (должен быть указатель на поток читателя, когда записываются потоки записи писем), который является независимым от платформы и ОС?

Благодаря

+0

Просьба представить образцы кода. –

+1

Вместо того, чтобы оживлять в читательском потоке, писатель (ы) должен [сигнализировать условие] (http://linux.die.net/man/3/pthread_cond_wait), который разблокирует мьютекс, который ожидает читатель. –

+0

Кроме того, если вы не очень осторожны в обеспечении того, чтобы авторы не обращались к одному региону буфера и не обновляли буфер во время чтения, вы получите условия гонки. –

ответ

2

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

Если C - единственный вариант, который у вас есть, вы можете использовать переменную состояния cnd_t, введенную C11 thread support library, но это может не поддерживаться более старыми компиляторами. В этом случае у вас все еще есть pthread_cond_t со всеми функциями синхронизации, такими как pthread_cond_wait/pthread_cond_signal, но я не знаю, не включена ли функция Windows под названием «Поддержка Pthread в Microsoft Windows Services для UNIX Версии 3.5», которая поддерживает потоковый материал POSIX в Windows наследство. Однако вы должны иметь возможность сделать тонкую оболочку вокруг объектов Windows HANDLE, которые бы имитировали поведение переменных состояния POSIX.

Если вы можете использовать C++, тогда вы можете использовать std::condition_variable, введенный C++ 11.

Заметки о поддержке C11

Поскольку вы упомянули вам нужно платформы независимого механизма следует отметить, что С11 не поддерживается в MSVC 2012 (который я могу по крайней мере, проверить себя) и ссылки о MSVC 2015 (например, this), в основном свидетельствуют о том, что там тоже не поддерживается.

+0

Я не вижу тег [tag: C++] по вопросу – Nazar554

+0

@ Nazar554 благодарю вас за то, что указали это, отрегулировали ответ так, чтобы он охватывал как C и C++. –

+0

Поскольку вы упомянули потоки C++ 11, возможно, стоит добавить некоторую информацию о C11 [condition variable] (http://en.cppreference.com/w/c/thread/cnd_init)? – Nazar554

1

То, что вы описываете (во втором абзаце), является разумным способом ожидать типичного планирования: когда процесс/поток отказывается от CPU, он возвращается в конец очереди.

Что вы можете сделать вместо этого, это сделать запись (-и) писателя, когда данные помещаются в очередь, используя условную переменную , а не использовать бесконечный цикл для чтения.

С помощью pthread_cond_wait() читатель может дождаться появления данных и используя pthread_cond_signal(), писатель (ы) уведомит читателя, чем данные готовы.

+0

Я не могу использовать какие-либо вызовы, связанные с потоком POSIX, поскольку мой код должен работать через разные которые будут иметь разную архитектуру ОС и процессоров. – user3899508

+0

Слитки C11 - это опция? Он не поддерживается полностью на большинстве платформ. Таким образом, потоки POSIX переносимы, по крайней мере, на nix-y-системах и, вероятно, единственный переносимый способ реализовать потоки в C, поскольку ситуация стоит на данный момент. –

Смежные вопросы