Стандарты программирования на С++. 101 правило и рекомендация | страница 25



Ссылки

[Brooks95] §19 • [McConnell93] §6.2 • [Parnas02] • [Stroustrup00] §24.4 • [SuttHysl04a]

12. Кодирование параллельных вычислений

Резюме

Если ваше приложение использует несколько потоков или процессов, следует минимизировать количество совместно используемых объектов, где это только можно (см. рекомендацию 10), и аккуратно работать с оставшимися.

Обсуждение

Работа с потоками — отдельная большая тема. Данная рекомендация оказалась в книге, потому что эта тема очень важна и требует рассмотрения. К сожалению, одна рекомендация не в силах сделать это полно и корректно, поэтому мы только резюмируем несколько наиболее важных положений и посоветуем обратиться к указанным ниже ссылкам за дополнительной информацией. Среди наиболее важных вопросов, касающихся параллельных вычислений, такие как избежание взаимоблокировок (deadlock), неустойчивых взаимоблокировок (livelock) и условий гонки (race conditions).

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

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

• Предпочтительно "обернуть" примитивы платформы в собственные абстракции. Это хорошая мысль, в особенности если вам требуется межплатформенная переносимость. Вы можете также воспользоваться библиотекой (например, pthreads [Butenhof97]), которая сделает это за вас.

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

 • гарантировать независимость объектов, которые не используются совместно. Два потока могут свободно использовать различные объекты без каких-либо специальных действий со стороны вызывающего кода;

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