Читать «UNIX: взаимодействие процессов» онлайн - страница 243
Уильям Ричард Стивенс
solaris # ls –l client4
-rwxrwxr-x 1 rstevens other1 139328 Apr 13 06:02 client4
solaris # chown root client4
solaris # chmod u+s client4
solaris # ls -l client4
-rwsrwxr-x 1 root other1 139328 Apr 13 06:02 client4
solaris # exit
solaris % ls -l client4
-rwsrwxr-x 1 root other1 139328 Apr 13 06:02 client4
solaris % client4 /tmp/server477
result: 5929
Если мы посмотрим, что в это время выводил сервер, то увидим следующую картину:
solaris % server4 /tmp/server4
euid = 224, ruid = 224, pid = 3168
euid = 0, ruid = 224, pid = 3176
Действующий идентификатор пользователя при втором запуске изменился. Значение 0 означает привилегированного пользователя.
Автоматическое управление потоками сервера
Чтобы посмотреть, как осуществляется управление потоками сервера, добавим в процедуру сервера команду выдачи ее идентификатора потока. Добавим в нее также пятисекундную паузу, чтобы имитировать длительное выполнение. За это время мы сможем запустить несколько клиентов. В листинге 15.6 приведен текст новой процедуры сервера.
Листинг 15.6. Процедура сервера, выводящая идентификатор потока
//doors/server5.c
1 #include "unpipc.h"
2 void
3 servproc(void *cookie, char *dataptr, size_t datasize,
4 door_desc_t *descptr, size_t ndesc)
5 {
6 long arg, result;
7 arg = *((long *) dataptr);
8 printf("thread id %ld, arg = %ld\n", pr_thread_id(NULL), arg);
9 sleep(5);
10 result = arg * arg;
11 Door_return((char*)&result, sizeof(result), NULL, 0);
12 }
Здесь используется новая функция из нашей библиотеки — pr_thread_id. Она принимает один аргумент (указатель на идентификатор потока или нулевой указатель вместо идентификатора вызвавшего потока) и возвращает идентификатор этого потока (обычно небольшое целое число, но всегда в формате длинного целого). Процессу всегда можно сопоставить целое число — его идентификатор. Хотя мы и не знаем, к какому типу принадлежит идентификатор процесса (int или long), мы просто преобразуем значение, возвращаемое getpid, к типу long и выводим значение (листинг 9.2). Однако идентификатор потока принадлежит к типу pthread_t, который не обязательно является одним из целых типов. И действительно, в Solaris 2.6 идентификаторами потоков являются короткие целые, тогда как в Digital Unix используются указатели. Однако часто возникает необходимость сопоставлять потокам небольшие целые числа для задач отладки (как в данном примере). Наша библиотечная функция, текст которой приведен в листинге 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 */