【问题标题】:Get name from PID?从 PID 中获取名称?
【发布时间】:2012-08-29 16:58:12
【问题描述】:

我在 OSX Mountain Lion 上,正在尝试使用其 PID 检索进程的名称。

以下是我正在使用的代码:

pid_t pid = 10687;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE] = "";
char nameBuffer [256] = "";

int sizeOfVal = sizeof(nameBuffer);
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));
proc_name(pid, nameBuffer, sizeof(nameBuffer));

NSLog(@"Path: %s\n Name: %s\n", pathBuffer, nameBuffer);

上面的代码能够正确检索名称,但是它只检索前 15 个字符并“忽略”其余字符。请注意,这不是显示名称的问题,而是 检索 它。问题不在于我的应用程序的其余部分,因为我正在独立应用程序中测试上述代码。另请注意,我尝试更改 PID,但无论我尝试什么 PID,代码仅检索名称的前 15 个字符。路径检索工作完美。

有人知道我做错了什么吗?

【问题讨论】:

  • 当我调查这个问题时,我发现了一些更奇怪的地方。如果指定的缓冲区长度小于 32 字节,则不会将任何内容放入字符串中,即使名称很短(并且适合 31 字节的缓冲区)

标签: objective-c c macos unix process


【解决方案1】:

函数查看的值是结构proc_bsdshortinfo。它仅限于返回一个 16 字节的字符串,或包含空终止符时的 15 个可读字符。

来自sys/param.h:

#define MAXCOMLEN   16      /* max command name remembered */

来自sys/proc_info.h:

struct proc_bsdshortinfo {
        uint32_t                pbsi_pid;       /* process id */
        uint32_t                pbsi_ppid;      /* process parent id */
        uint32_t                pbsi_pgid;      /* process perp id */
    uint32_t                pbsi_status;        /* p_stat value, SZOMB, SRUN, etc */
    char                    pbsi_comm[MAXCOMLEN];   /* upto 16 characters of process name */
    uint32_t                pbsi_flags;              /* 64bit; emulated etc */
        uid_t                   pbsi_uid;       /* current uid on process */
        gid_t                   pbsi_gid;       /* current gid on process */
        uid_t                   pbsi_ruid;      /* current ruid on process */
        gid_t                   pbsi_rgid;      /* current tgid on process */
        uid_t                   pbsi_svuid;     /* current svuid on process */
        gid_t                   pbsi_svgid;     /* current svgid on process */
        uint32_t                pbsi_rfu;       /* reserved for future use*/
};

编辑:要解决这个问题,请获取最后一个路径组件:

pid_t pid = 3051;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE];
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));

char nameBuffer[256];

int position = strlen(pathBuffer);
while(position >= 0 && pathBuffer[position] != '/')
{
    position--;
}

strcpy(nameBuffer, pathBuffer + position + 1);

printf("path: %s\n\nname:%s\n\n", pathBuffer, nameBuffer);

【讨论】:

  • 获取完整路径,然后将字符串修剪到最后一个路径组件。
  • 没有更优雅的解决方案吗?考虑到检索进程信息是许多程序的重要组成部分,应该有一个更有效的接口来检索此类信息。
  • 虽然检索进程信息很重要,但大多数应用程序甚至都不关心名称是什么。
  • 我明白了。感谢您的帮助。
  • 如果您查看像 ps 这样的程序的源代码,这就是它们获得长名称的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 2023-04-10
  • 2021-08-19
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多