Жанры книг
Мы в соц.сетях
ParaKnig📚 » Компьютеры и Интернет » Интернет » QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович
<< На главную

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 87 88 89 90 91 92 93 94 95 ... 106
Перейти на страницу:

// &quot;базовая часть&quot; команды devctl(), конкретный код команды будет

// формироваться динамически на основе этой части, но исходя

// из фактической длины блока передаваемых данных

const unsigned int DCMD_CMD = 1,

 DCMD_SRR = _POSIX_DEVDIR_TOFROM + (_DCMD_NET &lt;&lt; 8) + DCMD_CMD;

// структура ответов менеджера ресурса по запросу read()

struct result {

 pid_t pid;

 int chid;

 uint64_t cps;

 result(void) {

  pid = getpid();

  // если уж возвращать, то и служебную информацию ;)

  cps = SYSPAGE_ENTRY(qtime)-&gt;cycles_per_sec;

 }

}

// завершение с извещением кода причины

inline void exit(const char *msg) {

 cout &lt;&lt; 'r';

 perror(msg);

 exit(EXIT_FAILURE);

}

В этой части каких-либо комментариев заслуживает разве что структура result. Наш сервер устроен «наоборот»: информационный обмен данными он осуществляет по запросу devctl(), запрос read()нам «не нужен», и мы используем его только для возврата информации (PID + CHID) об автономном канале обмена сообщениями. Заодно мы передаем в поле cps этой структуры значение тактовой частоты процессора сервера, что позволяет знать, «с кем мы имеем дело» при экспериментах в сети.

Теперь мы вполне готовы написать код сервера. Этот сервер ( файл srv.cc), в отличие от традиционных, имеет два независимых канала подключения: как менеджер ресурсов и как сервер простого обмена сообщениями. Как менеджер он по запросу read()возвращает адресные компоненты (PID, CHID) для обмена сообщениями (ND клиент должен восстановить самостоятельно). По запросу devctl(), а также по запросу по автономному каналу обмена сообщениями сервер просто ретранслирует обратно полученный от клиента блок данных (в каком-то смысле по обоим каналам обмена наш сервер является «зеркалом», отражающим данные).

Сервер запросов

result data;

//---------------------------------------------------------

// реализация обработчика read()

static int readfunc(resmgr_context_t *ctp, io_read_t *msg,

 iofunc_ocb_t *ocb) {

 int sts = iofunc_read_verify(ctp, msg, ocb, NULL);

 if (sts != EOK) return sts;

 // возвращать одни и те же статические данные...

 MsgReply(ctp-&gt;rcvid, sizeof(result), &amp;data, sizeof(result));

 return _RESMGR_NOREPLY;

}

//---------------------------------------------------------

// реализация обработчика devctl.

static int devctlfunc(resmgr_context_t *ctp, io_devctl_t *msg,

 iofunc_ocb_t *ocb) {

 int sts = iofunc_devctl_default(ctp, msg, ocb);

 if (sts != _RESMGR_DEFAULT) return sts;

 // разбор динамически создаваемого кода devctl(),

 // извлечение из него длины принятого блока

 unsigned int nbytes = (msg-&gt;i.dcmd - DCMD_SRR) &gt;&gt; 16;

 msg-&gt;o.nbytes = nbytes;

 // и тут же ретрансляция блока назад

 return _RESMGR_PTR(ctp, &amp;msg-&gt;i, sizeof(msg-&gt;i) + nbytes);

}

//---------------------------------------------------------

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

// в отдельном потоке

static void* install(void* data) {

 dispatch_t *dpp;

 if ((dpp = dispatch_create()) == NULL)

  exit(&quot;dispatch allocate&quot;);

 resmgr_attr_t resmgr_attr;

 memset(&amp;resmgr_attr, 0, sizeof(resmgr_attr));

 resmgr_attr.nparts_max = 1;

 resmgr_attr.msg_max_size = 2048;

 static resmgr_connect_funcs_t connect_funcs;

 static resmgr_io_funcs_t io_funcs;

 iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &amp;connect_funcs,

  _RESMGR_IO_NFUNCS, &amp;io_funcs);

 // определяем обработку, отличную от обработки по умолчанию,

 // только для двух команд: read() &amp; devctl()

 io_funcs.read = &amp;readfunc;

 io_funcs.devctl = &amp;devctlfunc;

 static iofunc_attr_t attr;

 iofunc_attr_init(&amp;attr, S_IFNAM | 0666, 0, 0);

 // связываем менеджер с его префиксным именем

 if (resmgr_attach(dpp, &amp;resmgr_attr, DEVNAME,

  _FTYPE_ANY, 0, &amp;connect_funcs, &amp;io_funcs, &amp;attr) == -1)

  exit(&quot;prefix attach&quot;);

 dispatch_context_t* ctp = dispatch_context_alloc(dpp);

 while (true) {

  if ((ctp = dispatch_block(ctp)) == NULL)

1 ... 87 88 89 90 91 92 93 94 95 ... 106
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Лариса
Лариса 11.03.2026 - 20:17
Странно,здесь имя девочки Аграфена,а на других сайтах я прослушала три книги этого цикла с именем Дарвина.Зачем менять имя и путать читателей? Опечатка- не Дарвина,  а  Дарина.
Григорий
Григорий 09.04.2025 - 22:24
Лучшая книга всех времен
Женя
Женя 02.04.2025 - 16:08
Любимая книга