Программный Поиск Процесса По Имени В Qnx 6.5.0

Время от времени при разработке приложений в ОС РТ QNX 6.5.0 возникает задача найти процесс, зная только его символическое имя, или узнать некоторую информацию о процессе, или собрать некоторую статистику о процессе.

Это может понадобиться для широкого круга задач.



Программный поиск процесса по имени в QNX 6.5.0

Эта задача платформенно-специфична и единое кроссплатформенное решение доступно только в виде сторонних библиотек.

В этой статье мы реализуем небольшой класс-обертку, который позволяет нам получать информацию о процессе, зная только его имя.

Мы будем использовать С++.

Для выполнения задачи можно использовать системный вызов «system», вызывая утилиту работы с процессами «pidin», обрабатывая вывод этой утилиты.

Но это решение нас мало интересует. Итак, начнем с того, что в QNX первичной организационной структурой (в отличие, например, от Linux) является поток.

Ядро занимается исключительно планированием потоков.

Процессы — это контейнеры, содержащие один или несколько потоков.

Вся работа с процессами передана менеджеру процессов procnto. Этот менеджер ресурсов создает виртуальный каталог /proc/.

Попробуем отобразить содержимое этого каталога.

  
  
  
  
  
   

# ls /proc/ total 41 dr-xr-xr-x 2 root root 1 Sep 04 22:37 1 dr-xr-xr-x 2 root root 1 Sep 04 22:37 110611 dr-xr-xr-x 2 root root 1 Sep 04 22:37 126996 dr-xr-xr-x 2 root root 1 Sep 04 22:37 2 dr-xr-xr-x 2 root root 1 Sep 04 22:37 20489 drwxr-xr-x 2 root root 50 Jul 09 2010 boot nrw------- 1 root root 0 Sep 04 18:15 dumper dr-xr-xr-x 4 root root 1 Sep 04 22:37 self

Я немного сократил вывод утилиты, чтобы сэкономить место.

Вы можете заметить, что выходные данные содержат: 1) каталоги с PID запущенных процессов 2) Виртуальный каталог «boot», в котором хранятся файлы, «скомпилированные» в образ ОС.

3) Файл дампера, используемый утилитой «core dump».

4) Каталог «self» аналогичен каталогам с PID, но предоставляет данные для текущего процесса (в нашем случае ls).

Каталоги с PID содержат один файл с именем «as», который нельзя прочитать или записать с помощью стандартных файловых утилит QNX. Но, с другой стороны, к этим файлам (а по сути и менеджеру procnto) можно получить доступ с помощью системного вызова devctl. Предоставляется полная информация по работе с менеджером procnto. здесь .

Именно это мы и постараемся использовать в разрабатываемом классе.

Как видите, имя отделено от остальной информации devctl. Поэтому мы определим в классе два приватных поля — поле, хранящее имя процесса и системную информацию (системная информация о процессе хранится в структуре типа «debug_process_t»).

Итак, сначала давайте определим публичный интерфейс нашего класса.

Сохраним информацию о конкретном процессе в отдельном классе QNXProcInfo. Поскольку этому классу соответствует один конкретный процесс, вполне логично, что его конструктор будет брать pid процесса (в отличие от имени — pid уникален для каждого процесса, работающего в системе).

Для начала пусть он научится давать нам имя процесса, которому он соответствует, и выводить в поток информацию о себе в текстовом виде.

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

class QNXProcInfo { public: QNXProcInfo(int pid); std::string GetName(); void PrintInfo(std::ostream &out = std::cout); debug_process_t GetInfo(); private: std::string* name; debug_process_t info; };

Чтобы найти процесс, давайте определим еще один класс QNXProcMgr. Требуется искать процессы по имени и по переданной в компаратор функции.

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

class QNXProcMgr { public: static QNXProcInfo* Find(std::string pname); static QNXProcInfo* Find(bool (*comparator)(debug_process_t info)); };

Приступим к реализации.

Для получения информации об имени процесса мы используем пользовательскую структуру имени, содержащую структуру procfs_debuginfo и свободный буфер, в который будет записано имя процесса.

Код будет выглядеть примерно так:

QNXProcInfo::QNXProcInfo(int pid) { char paths[PATH_MAX]; int fd; static struct { procfs_debuginfo info; char buff [PATH_MAX]; } name; sprintf(paths, "/proc/%d/as", pid); if ((fd = open (paths, O_RDONLY)) == -1) { //FIXME: Add error handler here } devctl(fd, DCMD_PROC_MAPDEBUG_BASE, &name, sizeof(name), 0); this->name = new string(name.info.path); devctl(fd, DCMD_PROC_INFO, &info, sizeof(info), 0); close (fd); }

Как видите, для получения имени мы используем команду devctl DCMD_PROC_MAPDEBUG_BASE, при получении которой procnto заполняет переданную ему структуру и записывает имя в буфер пути.

Для получения другой информации используйте команду devctl DCMD_PROC_INFO, при получении которой procnto заполняет информационную структуру, которую мы передаем ему в качестве параметра.

Функции получения имени и отображения информации о процессе выглядят совершенно тривиально и описываться не будут. Стоит только отметить, что информацию о полях структуры debug_process_t можно найти здесь .

Перейдем к рассмотрению функционала класса, отвечающего за поиск процесса.

Вот код, отвечающий за поиск процесса по имени:

QNXProcInfo* QNXProcMgr::Find(string pname) { struct dirent *dirent; DIR *dir; int pid; string name; QNXProcInfo *info; if (!(dir = opendir ("/proc"))) throw QNXProcException("couldn't open /proc"); while ((dirent = readdir(dir))) { if (isdigit(*dirent->d_name)) { pid = atoi(dirent->d_name); info = new QNXProcInfo(pid); name = info->GetName(); if (name == pname) return info; else delete info; } } closedir (dir); throw QNXProcException("Process not found"); }

Как видите, используется простой поиск файлов в каталоге /proc, для каждого из найденных файлов (если это PID) создается новый объект ProcInfo, который проверяется на соответствие условию, и если это PID не совпадает, удаляется.

Функция поиска по функции-компаратору выглядит так:

QNXProcInfo* QNXProcMgr::Find(bool (*comparator)(debug_process_t info)) { struct dirent *dirent; DIR *dir; int pid; QNXProcInfo *info; if (!(dir = opendir ("/proc"))) throw QNXProcException("couldn't open /proc"); while ((dirent = readdir(dir))) { if (isdigit(*dirent->d_name)) { pid = atoi(dirent->d_name); info = new QNXProcInfo(pid); if (comparator(info->GetInfo())) return info; else delete info; } } closedir (dir); throw QNXProcException("Process not found"); }

Вот и все.

При необходимости читатель может расширить и дополнить эти занятия в соответствии со своими потребностями.

Также следует отметить, что код не претендует на полноту.

В нем отсутствует обработка некоторых типов ошибок, алгоритм поиска не оптимально структурирован, функция поиска должна уметь возвращать несколько объектов QNXProcInfo (поскольку одному имени могут соответствовать несколько процессов) и многое-многое другое.

Но я уверен, что читатель вполне справится с этим самостоятельно.

Данная статья была призвана лишь показать направление деятельности.

Полные исходники доступны по адресу связь .

Теги: #qnx #neutrino #Системное программирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.