QNX 6.5.0でプログラムで名前でプロセスを検索する

定期的に、RV QNX 6.5.0 OSでアプリケーションを開発するとき、タスクは、そのシンボル名のみを知っているプロセスを見つけるか、プロセスに関する情報を見つけるか、プロセスに関する統計を収集するというタスクが発生します。 これは、広範囲のタスクに必要な場合があります。



画像



このタスクはプラットフォーム固有であり、単一のクロスプラットフォームソリューションはサードパーティライブラリの形式でのみ利用可能です。



この記事では、名前だけを知っているプロセスに関する情報を取得できる小さな「ラッパー」クラスを実装します。 YaP C ++を使用します。



このタスクを実行するには、「システム」システムコールを使用して、「pidin」プロセスを操作するユーティリティを呼び出し、このユーティリティの出力を処理します。 しかし、このソリューションは私たちにはほとんど関心がありません。



それでは、QNXの主要な組織構造(たとえばLinuxとは異なります)がストリームであるという事実から始めましょう。 カーネルはスレッドのスケジューリングのみを扱います。 プロセスは、1つ以上のスレッドを含むコンテナです。 プロセスに関するすべての作業は、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」。OSイメージに「コンパイル」されたファイルを保存します。

3)コアダンプユーティリティで使用されるダンプファイル

4)「self」ディレクトリはPIDのディレクトリに似ていますが、現在のプロセス(この場合はls)のデータを提供します。



PIDのあるディレクトリには、「as」という名前の単一のファイルがあり、ファイルを操作する通常のQNXユーティリティでは読み取りも書き込みもできません。 ただし、これらのファイル(および実際にはprocntoマネージャー)は、devctlシステムコールを使用してアクセスできます。 procntoマネージャーでの作業に関する完全な情報は、 ここに表示されます



開発中のクラスでこれを活用しようとします。 ご覧のとおり、名前はdevctlの残りの情報とは別に取得されます。 したがって、クラスに2つのプライベートフィールドを定義します。プロセス名とシステム情報を格納するフィールドです(プロセスに関するシステム情報は、タイプ "debug_process_t"の構造に格納されます)。



まず、クラスのパブリックインターフェイスを定義しましょう。 特定のプロセスに関する情報を別のクラスQNXProcInfoに保存してみましょう。 このクラスは1つの特定のプロセスに対応するため、そのコンストラクターがプロセスの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が渡された構造を埋め、名前をパスバッファーに書き込むかを受け取ります。



他の情報については、DCMD_PROC_INFO devctlコマンドが使用され、どのprocntoがinfo構造を埋めるかを受け取り、それをパラメーターとして渡します。



名前を取得し、プロセスに関する情報を表示する機能は完全に簡単に見えるため、説明しません。 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オブジェクトが作成され、条件に準拠しているかどうかがチェックされ、一致しない場合は削除されます。



コンパレータの関数を検索する関数のように見えます:



 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オブジェクト(複数のプロセスが1つの名前に対応できるため)を返すことができるはずです。 しかし、読者は自分でこれに完全に対処すると確信しています。 この記事は、活動の方向を示すことのみを目的としていました。



完全なソースはこちらから入手できます



All Articles