My-library.info
Все категории

QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович. Жанр: Интернет год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
QNX/UNIX: Анатомия параллелизма
Дата добавления:
17 сентябрь 2020
Количество просмотров:
162
Читать онлайн
QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович

QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович краткое содержание

QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович - описание и краткое содержание, автор Цилюрик Олег Иванович, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info

Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.

В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.

QNX/UNIX: Анатомия параллелизма читать онлайн бесплатно

QNX/UNIX: Анатомия параллелизма - читать книгу онлайн бесплатно, автор Цилюрик Олег Иванович

Далее следует код

SingleProc()
, преобразованный в многопоточный вид:

static pthread_key_t key;

static pthread_once_t once = PTHREAD_ONCE_INIT;

static void destructor(void* db) {

 delete (DataBlock*)db;

}

static void once_creator(void) {

 // создается единый на процесс ключ для данных DataBlock:

 pthread_key_create(&key, destructor);

}

void* ThreadProc(void *data) {

 // гарантия того, что ключ инициализируется только 1 раз на процесс!

 pthread_once(&once, once_creator);

 if (pthread_getspecific(key) == NULL)

  pthread_setspecific(key, new DataBlock(...));

 // Теперь каждый раз в теле этой функции или функций, вызываемых

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

 DataBlock* pdb = pthread_getspecific(key);

 // ... все те же операции с полями pdb->(DataBlock)

 return NULL;

}

Примечание

Обратите внимание, что вся описанная техника преобразования потоковых функций в реентерабельные (как и все программные интерфейсы POSIX) отчетливо ориентирована на семантику классического С, в то время как все свое изложение мы ориентируем и иллюстрируем на С++. При создании экземпляра собственных данных полностью разрушается контроль типизации: разные экземпляры потоков вполне могли бы присвоить своим указателям данные (типа v

oid*
), ассоциированные с одним значением
key
. Это совершенно различные типы данных, скажем
DataBlock_1*
и
DataBlock_2*
. Но проявилось бы это несоответствие только при завершении функции потока и уничтожении экземпляров данных, когда к объектам совершенно разного типа был бы применен один деструктор, определенный при выделении ключа. Ошибки такого рода крайне сложны в локализации.

Особая область, в которой собственные данные потока могут найти применение и где локальные (стековые) переменные потока не могут быть использованы, — это асинхронное выполнение фрагмента кода в контексте потока, например при получении потоком сигнала.

Еще одно совсем не очевидное применение собственных данных потока (мы не встречали в литературе упоминаний о нем), которое особо органично вписывается в использование именно С++, — это еще один способ возврата в родительский поток результатов работы дочерних. При этом неважно, как были определены дочерние потоки - как присоединенные или как отсоединенные (мы обсуждали это ранее); такое использование в заметной мере нивелирует их разницу. Эта техника состоит в том, что:

• Если при создании ключа не определять деструктор экземпляра данных потока

pthread_key_create(..., NULL)
, то при завершении потока над экземпляром его данных не будут выполняться никакие деструктивные действия и созданные потоками экземпляры данных будут существовать и после завершения потоков.

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

В коде (что гораздо нагляднее) это может выглядеть так (код с заметными упрощениями взят из реального завершенного проекта):

// описание экземпляра данных потока

struct throwndata {

 ...

};

static pthread_once_t once = PTHREAD_ONCE_INIT;

static pthread_key_t key;

void createkey(void) { pthread_key_create(&key, NULL); }

// STL-очередь, например указателей на экземпляры данных

queue<throwndata*> result;

// функция потока

void* GetBlock(void*) {

 pthread_once(&once, createkey);

 throwndata *td;

 if ((td = (throwndata*)pthread_getspecific(key)) == NULL) {

  td = new throwndata();

  pthread_setspecific(key, (void*)td);

  // вот он - альтернативный путь доступа:

  result.push(td);

 }

 // далее идет плодотворная работа над блоком данных *td

 // . . . . . . . . .

}

int main(int argc, char **argv) {

 // . . . . . .

 for (int i = 0; i < N; i++)

  pthread_create(NULL, NULL, GetBlock, NULL);

 // . . . . . . к этому времени потоки завершились;

 // ни в коем случае нельзя помещать result.size()

 // непосредственно в параметр цикла!

 int n = result.size();

 for (int i = 0; i < n; i++) {

  throwndata *d = result.front();

  // обработка очередного блока *d ...

  result pop();

  delete d;

 }

 return EXIT_SUCCESS;

}

Примечание

В предыдущих примерах кода мы указывали третий параметр

pthread_create()
в виде
&GetBlock
(адреса функции потока), но в текущем примере мы сознательно записали
GetBlock
. И то и другое верно, ибо компилятор достаточно умен, чтобы при указании имени функции взять ее адрес.


Цилюрик Олег Иванович читать все книги автора по порядку

Цилюрик Олег Иванович - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


QNX/UNIX: Анатомия параллелизма отзывы

Отзывы читателей о книге QNX/UNIX: Анатомия параллелизма, автор: Цилюрик Олег Иванович. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.