Читать «UNIX: взаимодействие процессов» онлайн - страница 253

Уильям Ричард Стивенс

44 {

45  if (argc != 2)

46  err_quit("usage: server6 <server-pathname>");

47  Door_server_create(my_create);

48  /* создание дескриптора двери и связывание его с именем */

49  Pthread_mutex_lock(&fdlock);

50  fd = Door_create(servproc, NULL, DOOR_PRIVATE);

51  Pthread_mutex_unlock(&fdlock);

52  unlink(argv[1]);

53  Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE));

54  Fattach(fd, argv[1]);

55  /* servproc() обслуживает запросы клиентов */

56  for(;;)

57   pause();

58 }

По сравнению с листингом 15.2 было внесено четыре изменения:

1. Убрано объявление дескриптора двери fd (теперь это глобальная переменная, описанная в листинге 15.18).

2. Вызов door_create защищен взаимным исключением (также описанным в листинге 15.18).

3. Вызов door_server_create делается перед созданием двери, при этом указывается процедура создания сервера (my_thread, которая, будет показана позже).

4. В вызове door_create последний аргумент (атрибуты) имеет значение DOOR_PRIVATE вместо 0. Это говорит библиотеке о том, что данная дверь будет иметь собственный пул потоков, называемый частным пулом сервера.

Задание процедуры создания сервера с помощью door_server_create и выделение частного пула сервера с помощью DOOR_PRIVATE осуществляются независимо друг от друга. Возможны четыре ситуации:

1. По умолчанию частный пул сервера и процедура создания сервера отсутствуют. Система создает потоки по мере необходимости и они переходят в пул потоков процесса.

2. Указан флаг DOOR_PRIVATE, но процедура создания сервера отсутствует. Система создает потоки по мере необходимости и они отходят в пул потоков процесса, если относятся к тем дверям, для которых флаг DOOR_PRIVATE не был указан, либо в пул данной двери, если она была создана с флагом DOOR_PRIVATE.

3. Отсутствует частный пул сервера, но указана процедура создания сервера. Процедура создания вызывается при необходимости создания нового потока, который затем переходит в пул потоков процесса.

4. Указан флаг DOOR_PRIVATE и процедура создания сервера. Процедура создания сервера вызывается каждый раз при необходимости создания потока. После создания поток должен вызвать door_bind для отнесения его к нужному частному пулу сервера, иначе он будет добавлен к пулу потоков процесса.

В листинге 15.18 приведен текст двух новых функций: my_create (процедура создания сервера) и my_thread (функция, выполняемая каждым потоком, который создается my_create).

Листинг 15.18. Функции управления потоками

//doors/server6.c

13 pthread_mutex_t fdlock = PTHREAD_MUTEX_INITIALIZER;

14 static int fd = –1; /* дескриптор двери */

15 void *

16 my_thread(void *arg)

17 {

18  int oldstate;

19  door_info_t *iptr = arg;

20  if ((Door_server_proc*)iptr->di_proc == servproc) {

21   Pthread_mutex_lock(&fdlock);

22   Pthread_mutex_unlock(&fdlock);

23   Pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);

24   Door_bind(fd);

25   Door_return(NULL, 0, NULL, 0);

26  } else

27   err_quit("my_thread: unknown function: %p", arg);

28  return(NULL); /* никогда не выполняется */