Параллельное и распределенное программирование на С++ - [58]
Если значение параметра execute равно 0, указатель извлекается из вершины стека потока без выполнения routine -функции.
Необходимо позаботиться о том, чтобы для каждой функции занесения в стек (push) существовала функция извлечения из стека (pop) в пределах одной и той же лексической области видимости. Например, для функции funcA () обязательно выполнение cleanup -обработчика при ее нормальном завершении или аннулировании:
>void *funcA(void *X)
>{
> int *Tid;
> Tid = new int;
> // do some work
> //...
> pthread_cleanup_push(cleanup_funcA,Tid);
> // do some more work
> //...
> pthread_cleanup_pop(0);
>}
Здесь функция funcA( ) помещает указатель на обработчик cleanup_funcA( ) в стек завершающих процедур путем вызова функции pthread_cleanup_push (). Каждому обращению к этой функции должно соответствовать обращение к функции pthread_cleanup_pop(). Если функции извлечения указателя из стека (pop- функции) передается значение 0, то извлечение из стека состоится, но без выполнения обработчика. Обработчик будет выполнен лишь при аннулировании потока, выполняющего функцию funcA().
Для функции funcB () также требуется cleanup -обработчик:
>void *funcB(void *X)
>{
> int *Tid;
> Tid = new int;
> // do some work
> //...
> pthread_cleanup_push(cleanup_funcB,Tid);
> // do some more work
> //...
> pthread_cleanup_pop(1);
>}
Здесь функция funcB () помещает указатель на обработчик cleanup_funcB () в стек завершающих процедур. Отличие этого примера от предыдущего состоит в том, что функции pthread_cleanup_pop () передается параметр со значением 1, т.е. после извлечения из стека указателя на обработчик этот обработчик будет тут же выполнен. Необходимо отметить, что выполнение обработчика в данном случае состоится «при любой погоде», т.е. и при аннулировании потока, который обеспечивает выполнение функции funcB( ), и при обычном его завершении. Обработчики- «уборщики», cleanup_funcA() и cleanup_funcB (), — это обычные функции, которые можно использовать для закрытия файлов, освобождения ресурсов, разблокирования мьютексов и пр.
Управление стеком потока
Адресное пространство процесса делится на раздел кода, раздел статических данных, свободную память и раздел стеков. Стекам потоков выделяется область из стекового раздела процесса. Стек потока предназначен для хранения стекового фрейма, связанного с каждой процедурой (функцией), которая была вызвана, но еще не завершена. Стековый фрейм содержит временные переменные, локальные переменные, адреса точек возврата и любую другую дополнительную информацию, которая необходима потоку, чтобы найти «обратную дорогу» к ранее вызванным процедурам. При выходе из процедуры (функции) ее стековый фрейм извлекается из стека. Расположение фреймов в стеке схематично показано на рис. 4.12.
Предположим, что поток А (см. рис. 4.12) выполняет функцию task1 () , которая создает некоторые локальные переменные, выполняет заданную обработку, а затем вызывает функцию taskX (). При этом для функции task1 () создается стековый фрейм, который помещается в стек потока. Функция taskX () выполняет «свои» действия, создает локальные переменные, а затем вызывает функцию taskC (). Нетрудно догадаться, что стековый фрейм, созданный для функции taskX () , также помещается в стек. Функция taskC () вызывает функцию taskY() и т.д. Каждый стек должен иметь достаточно большой размер, чтобы поместить всю информацию, необходимую для выполнения всех функций потока, а также цепочки других подпрограмм, которые будут вызваны потоковыми функциями. Размером и местоположением стека потока управляет операционная система, но для установки и считывания этой информации предусмотрены методы, которые определены в объекте атрибутов потока.
Рис. 4.12. Стековые фреймы, сгенерированные потоками
Функция pthread_attr_getstacksize( ) возвращает минимальный размер стека, устанавливаемый по умолчанию. Параметр attr определяет объект атрибутов потока, из которого считывается стандартный размер стека. При успешном выполнении функция возвращает значение 0, а стандартный размер стека, выраженный в байтах, coxpaняется в параметре stacksize. В случае неудачи функция возвращает код ошибки.
Функция pthread_attr_setstacksize() устанавливает минимальный размер стека. Параметр attr определяет объект атрибутов потока, для которого устанавливается размер стека. Параметр stacksize содержит минимальный размер стека, выраженный в байтах. При успешном выполнении функция возвращает значение 0 , в противном случае - код ошибки. Функция завершается неудачно, если значение параметра stacksize оказывается меньше значения PTHREAD_MIN_STACK или превышает системный минимум. Вероятно, значение PTHREAD_STACK_MIN будет меньше минимального размера стека, возвращаемого функцией p thread_attr_getstacksize(). Прежде чем увеличивать минимальный размер стека потока, следует поинтересоваться значением, возвращаемым функцией p thread_attr_getstacksize() р азмер ст ека фиксируется, чтобы его расширение во время выполнения программы ограничивалось рамками фиксированного пространства стека, установленного во время компиляции.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.