на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



15.7. Примеры

В этом разделе мы приведем примеры использования пяти только что описанных функций.


Листинг 15.7. Функция pr_thread_id: возвращает небольшой целочисленный идентификатор потока

//lib/wrappthread.c

245 long

246 pr_thread_id(pthread_t *ptr)

247 {

248 #if defined(sun)

249  return((ptr == NULL) ? pthread_self() : *ptr); /* Solaris */

250 #elif defined(__osf__) && defined(__alpha)

251  pthread_t tid;

252  tid = (ptr == NULL) ? pthread_self() : *ptr; /* Digital Unix */

253  return(pthread_getsequence_np(tid));

254 #else

255  /* прочие системы */

256  return((ptr == NULL) ? pthread_self() : *ptr);

257 #endif

258 }

Если в данной реализации идентификатор потока не является небольшим целым числом, функция может быть сложнее. Она может осуществлять отображение значений типа pthread_t в целые числа и сохранять эти отображения для последующих вызовов в массиве или связном списке. Эта задача решена в функции thread_name в книге [13].

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

solaris % client5 /tmp/server5 55

result: 3025

solaris % client5 /tmp/server5 66

result: 4356

solaris % client5 /tmp/server5 77

result: 5929

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

solaris % server5 /tmp/server5

thread id 4, arg = 55

thread id 4, arg = 66

thread id 4, arg = 77

Теперь запустим три экземпляра программы-клиента одновременно:

solaris % client5 /tmp/server5 11 & client5 /tmp/server5 22 & client5 /tmp/server5 33 &

[2] 3812

[3] 3813

[4] 3814

solaris % result: 484

result: 121

result: 1089

Выводимый сервером текст показывает, что для обработки второго и третьего вызова процедуры сервера создаются новые потоки:

thread id 4, arg = 22

thread id 5, arg = 11

thread id 6, arg = 33

Затем мы запустим еще два клиента одновременно (первые три уже завершили работу):

solaris % client5 /tmp/server5 11 & client5 /tmp/server5 22 &

[2] 3830

[3] 3831

solaris % result: 484

result: 121

При этом сервер использует созданные ранее потоки:

thread id 6, arg = 22

thread id 5, arg = 11

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

Мы также убедились, что сервер в этом случае является параллельным (concurrent): одновременно может выполняться несколько экземпляров процедуры сервера в виде отдельных потоков для обслуживания клиентов. Это следует также из того, что результат работы сервера выводится тремя экземплярами клиента одновременно пять секунд спустя после их одновременного запуска. Если бы сервер был последовательным, первый результат появился бы через 5 секунд после запуска, следующий — через 10, а последний — через 15.


15.6. Функция door_info | UNIX: взаимодействие процессов | Функция door_info