|
Программирование >> Формирование пользовательского контейнера
0огопаточностъ 147 Задания для самостоятельной работы разработка многопоточных программ может быть очень азартным занятием. Основная причина состоит в том, что многозадачность требует от вас предоставления программы как совокупности параллельно выполняющихся фрагментов, а не линейной последовательности операций. Более того, во время выполнения поведение потоков часто трудно предугадать. Таким образом, вы можете быть удивлены (или даже сбиты с толку) действиями многопо-чных программ. Лучший способ освоить многопоточность - поэкспериментировать с ней. В конце приведу несколько задач, которые вы, может быть, захотите решить. Попробуйте разместить на панели управления потоком еще один элемент управления - список, который позволит пользователю регулировать не только текущее значение приоритета потока, но и его класс приоритета. Расположите на панели управления разные объекты синхронизации, которые пользователь сможет включать и отключать по своему усмотрению. Это позволит вам проверить разные параметры и режимы синхронизации. Попытайтесь с помощью многопоточного сборщика мусора реже проводить очистку памяти, например, когда список gclist достигнет определенного размера или когда объем свободной памяти сократится до заданного размера. Как альтернативу вы можете использовать таймер ожидания для регулярного сбора мусора. В конце концов, можно поэкспериментировать с классом приоритета и текущим значением приоритета сборщика мусора, чтобы найти оптимум для вашей профаммы. Глава 4 расширение С++ Для типичного программиста, пишущего на языке С++, программирование - это не работа, а образ жизни. Мы, программисты, оцениваем не только явную силу языка, но и его нюансы и хитрости. Точно так же, как тонкие ценители, знающие толк в вине высшего качества, мы наслаждаемся элементами, украшающими язык. Конечно, наш интерес к С++ не ограничивается простым использованием его для написания программ. Напротив, нас привлекает язык как таковой и базовые идеи, связанные с разработкой и развитием языков программирования. Именно интересом большинства программистов к языку объясняется то, что редко кто из них не мечтал о включении в язык новых структур и функциональных возможностей. (Как часто вы думали: Как здорово было бы, если бы язык С++ имел... ) К сожалению, у большей части программистов нет доступа к исходному коду полноценного компилятора для С++, в который можно было бы вставить свои экспериментальные структурные элементы. Теперь появился легкий способ тестирования ваших собственных расширений языка С++ - создание транслятора, который превратит экспериментальные идеи в эквивалентный код на С++. Именно такой транслятор будет предметом обсуждения этой главы. Зачем нужен транслятор? Ьь1 Можете спросить, зачем понадобился транслятор для испытания новых Конструкций языка, когда есть хорошо знакомая альтернатива - стандартный препроцессор языка С++? Как известно всем читателям, препроцессор выполняет макроподстановки, в которых один текстовый фрагмент замещается другим. Долгое время макросы препроцессора использовались для вставки экспериментальных элементов в язык С++. Например, общеупотребительная Конструкция, реализуемая с помощью макроса, - цикл repeat/until. Этот Икл подобен циклу do/whiie языка С++, за исключением того, что цикл *®Peat/until выполняется до тех пор, пока некоторое условие не станет истинным (true). (Таким образом, цикл repeat/until выполняется, пока его логическое выражение равно false.) Именно это отличает его от цикла do/while, который функционирует до тех пор, пока некоторое условие не станет ложным. Благодаря подобию описанных циклов возможна реализация ци*Сг1а repeat/until с помощью макроса, как показано в приведенном далее фрагменте кода, ttdefine repeat do #define until(exp) while(!(exp)) ... int = 0; repeat { cout i: I endl; i++; } until(i == 10); Макрос вызывает подстановку do вместо repeat и while вместо until. Условное выражение в while также меняется на противоположное. Таким образом, цикл repeat/until из предыдущего фрагмента преобразуется препроцессором в приведенный далее цикл do/while, do { cout i: I endl; i++; } whiled (i == 10)); Как показывает этот пример, применение макроса для реализации конструкции repeat/until - легкий И оправданный прием. Если существует многолетняя традиция применения макросов для создания новых элементов языка, захочет ли кто-нибудь разрабатывать транслятор для этой цели? Почему не использовать макрос, подобный тому, который применялся для цикла repeat/until? К сожалению, макроподстановки нельзя применять для встраивания всех типов экспериментальных конструкций языка. Более того, даже в тех случаях, когда подобные подстановки возможны, не все из них столь элегантны и концептуально чисты, как та, которая применялась в примере для цикла repeat/until. Несмотря на то, что программисты добились впечатляющих успехов с помощью макросов, в большинстве случаев они достигались за счет применения сложных и малопонятных директив #define Корректность подобных макрохитростей , часто нарушающих структуру кода и не обладающих достаточной отказоустойчивостью, трудно проверить. Честно говоря, многие программисты на С++ (и автор в том числе) избегают использования сложных макросов по этим причинам. К счастью, существует альтернатива применению сложных макросов, которая предназначена для экспериментов с разнообразными новыми элементами
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |