【问题标题】:C program to find the virtual memory used by a process on HP-UX?C程序在HP-UX上查找进程使用的虚拟内存?
【发布时间】:2011-05-07 04:53:31
【问题描述】:

在一次采访中问我这个问题:

  • 编写一个简单的 C 程序来查找 unix (HP-UX) 上正在运行的进程使用的虚拟内存

我告诉他们我不太确定,但也提出了一些想法,例如:

  • 也许我们可以使用getpid 系统调用获取进程ID,并将其与stat 一起使用并获得所需的输出
  • 或者我们可以运行system 函数调用,在其中我们可以使用ps 等shell 命令并获取详细信息。

也许我不正确;有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: c unix virtual-memory


    【解决方案1】:

    您可以使用 HP/UX 上的pstat_getprocvm 函数来了解进程的虚拟内存布局。

    示例取自here

    #ifdef PS_RSESTACK      /* 11.22 and later */
    #define LAST_VM_TYPE    PS_RSESTACK
    #else               /* prior non-IPF */
    #define LAST_VM_TYPE    PS_GRAPHICS_DMA
    #endif              /* PS_RSESTACK */
    
    uint32_t virt_totals[LAST_VM_TYPE + 1];
    uint32_t phys_totals[LAST_VM_TYPE + 1];
    uint32_t swap_totals[LAST_VM_TYPE + 1];
    uint32_t mlock_totals[LAST_VM_TYPE + 1];
    
    void print_type(int type)
    {
        switch (type) {
        case PS_USER_AREA:
          printf(" UAREA ");
          return;
        case PS_TEXT:
          printf(" TEXT ");
          return;
        case PS_DATA:
          printf(" DATA/HEAP ");
          return;
        case PS_STACK:
          printf(" MAIN STACK ");
          return;
    #ifdef PS_RSESTACK
          case PS_RSESTACK:
          printf(" RSE STACK ");
        return;
    #endif              /* PS_RSESTACK */
        case PS_IO:
          printf(" MEM MAPPED I/O ");
        return;
          case PS_SHARED_MEMORY:
        printf(" SYSV SHMEM ");
        return;
        case PS_NULLDEREF:
        printf(" NULL DEREF ");
        return;
        case PS_MMF:
        printf(" MMAP ");
        return;
        case PS_GRAPHICS:
        case PS_GRAPHICS_DMA:
          printf(" GRAPHICS SPECIFIC ");
          return;
        default:
          printf(" UNUSED TYPE ");
        }
        return;
    }
    
    int main(int argc, char *argv[])
    {
        int error;
        struct pst_vm_status pvs;
        struct pst_status ps;
        int i, j, k, verbose, get_all;
        pid_t target;
        int valid = 0;
        size_t sys_page_size;
        int done = 0;
        size_t count;
        _T_LONG_T last_pid = -1;
    
        verbose = 0;
        target = 0;
        get_all = 0;
    
        if (argc > 3) {
          printf("USAGE: %s <-v> \n", argv[0]);
        }
    
        if (argc == 2) {
          target = atoi(argv[1]);
        } else if (argc == 3) {
          verbose = 1;
          target = atoi(argv[2]);
        } else {
          get_all = 1;
        }
    
        sys_page_size = sysconf(_SC_PAGE_SIZE);
    
        j = 0;
    
        printf("VIRT/PHYS/LOCKED/SWAP summaries in pages.\n");
        printf("System page size is %ld or 0x%lx bytes.\n",
           sys_page_size, sys_page_size);
    
        do {
        if (get_all) {
            target = j++;
            count = (size_t) 1;
        } else {
            count = 0;
        }
       done = (pstat_getproc(&ps, sizeof(struct pst_status),
                      count, target) <= 0);
        if (done) {
            break;
        }
    
        if (ps.pst_pid == last_pid) {
            continue;
        }
    
        last_pid = ps.pst_pid;
    
        for (k = 0; k <= LAST_VM_TYPE; k++) {
            virt_totals[k] = 0;
            phys_totals[k] = 0;
            swap_totals[k] = 0;
            mlock_totals[k] = 0;
        }
    
        i = 0;
        while (pstat_getprocvm(&pvs, sizeof(struct pst_vm_status),
                       (size_t) ps.pst_pid, i++) > 0) {
    
            valid = 1;
    
            if (verbose) {
            printf("Object %d: ", i);
            print_type(pvs.pst_type);
            printf(" at VA 0x%lx to VA 0x%lx.\n\t",
                   pvs.pst_vaddr,
                   pvs.pst_vaddr +
                   (pvs.pst_length * sys_page_size) - 1);
            printf("\tVIRT: %ld \tPHYS: %ld \tLOCKED:"
                   " %ld\tSWAP: %ld \n",
                   pvs.pst_length, pvs.pst_phys_pages,
                   pvs.pst_lockmem, pvs.pst_swap);
            }
            virt_totals[pvs.pst_type] += pvs.pst_length;
            phys_totals[pvs.pst_type] += pvs.pst_phys_pages;
            swap_totals[pvs.pst_type] += pvs.pst_swap;
            mlock_totals[pvs.pst_type] += pvs.pst_lockmem;
        }
    
        if (valid) {
            printf("PID %ld:\n", ps.pst_pid);
        }
     for (k = 0; k <= LAST_VM_TYPE && valid; k++) {
            print_type(k);
            printf(" consumes %ld VIRT, %ld PHYS, %ld LOCKED"
               " and %ld SWAP.\n",
               virt_totals[k], phys_totals[k], mlock_totals[k],
               swap_totals[k]);
            virt_totals[k] = 0;
            phys_totals[k] = 0;
            mlock_totals[k] = 0;
            swap_totals[k] = 0;
        }
        valid = 0;
        } while (get_all);
    
        exit(0);
    

    【讨论】:

      【解决方案2】:

      使用getpid() 无济于事 - 它会告诉您当前进程的 PID,这可能不是您感兴趣的进程。

      使用stat() 无济于事 - 它会告诉您文件的大小。

      你有两个一个主要的选项选项-我不确定哪个最适合HP-UX。

      1. 使用/proc 文件系统和其中的信息来查找您需要的号码。在我可以访问的 HP-UX 11.23 机器上,没有/proc,所以这很可能不相关。
      2. 通过popen() 运行适当的ps 命令并解析输出。命令可能是ps -lp PID,其中 PID 是(我希望很明显)您感兴趣的进程的 PID。

      一些快速检查显示:

      • AIX、Solaris、Linux 有(三种不同的实现)/proc 文件系统。
      • HP-UX 和 MacOS X(以及其他 BSD 系统)没有 /proc 文件系统。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-13
        • 1970-01-01
        • 1970-01-01
        • 2012-08-12
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        相关资源
        最近更新 更多