zoukankan      html  css  js  c++  java
  • 进程控制(1):进程标识符

        进程标识符(PID)是一个进程的基本属性,其作用类似于每个人的身份证号码。根据进程标识符,用户可以精确地定位一个进程。一个进程标识符唯一对应一个进程,而多个进程标识符可以对应同一个程序。本文将深入探讨进程标识符及其相关操作。


    1 进程标识符

        每个进程在系统中都有唯一的一个ID标识它,这个ID就是进程标识符(PID)。因为其唯一,所以系统可以根据它准确定位到一个进程。进程标识符的类型为pid_t,其本质上是一个无符号整型的类型别名(typedef)。

        接下来,我们来简单介绍一个进程与程序的关系。所谓程序,不过是指可运行的二进制代码文件,把这种文件加载到内存中运行就得到了一个进程。同一个程序文件可以被加载多次成为不同的进程。因此,进程与进程标识符之间是一对一的关系,而与程序文件之间是多对一的关系。

    1

    在Linux shell中,可以使用ps命令查看当前用户所使用的进程。

    xiaomanon@xiaomanon-machine:~$ ps -u xiaomanon
      PID TTY          TIME CMD
     1296 ?        00:00:00 init
     1357 ?        00:00:00 sh
     1359 ?        00:00:00 sleep
     1362 ?        00:00:01 dbus-daemon
     1371 ?        00:00:00 upstart-event-b
     1375 ?        00:00:00 window-stack-br
     1383 ?        00:00:00 gnome-keyring-d
     1393 ?        00:00:00 upstart-file-br
     1410 ?        00:00:00 bamfdaemon
     1414 ?        00:00:00 upstart-dbus-br
     1418 ?        00:00:00 upstart-dbus-br
     1419 ?        00:00:00 ibus-daemon
     1428 ?        00:00:00 gvfsd
     1460 ?        00:00:00 unity-settings-
     1482 ?        00:00:00 hud-service
     1492 ?        00:00:00 at-spi-bus-laun
     1495 ?        00:00:00 gvfsd-fuse
     1497 ?        00:00:00 gnome-session
     1498 ?        00:00:00 dbus-daemon
     1506 ?        00:00:00 ibus-dconf
     1507 ?        00:00:00 ibus-ui-gtk3
     1510 ?        00:00:01 unity-panel-ser
     1512 ?        00:00:00 ibus-x11
     1523 ?        00:00:00 at-spi2-registr
     1600 ?        00:00:00 indicator-messa
     1605 ?        00:00:00 indicator-bluet
     1610 ?        00:00:00 indicator-keybo
     1615 ?        00:00:00 indicator-power
     1625 ?        00:00:00 indicator-datet
     1627 ?        00:00:00 indicator-sound
     1630 ?        00:00:00 indicator-print
     1635 ?        00:00:00 indicator-sessi
     1653 ?        00:00:00 indicator-appli
     1666 ?        00:00:00 evolution-sourc
     1680 ?        00:00:00 pulseaudio
     1733 ?        00:00:00 ibus-engine-sim
     1793 ?        00:00:00 dconf-service
     1795 ?        00:00:00 notify-osd
     1860 ?        00:00:05 compiz
     1901 ?        00:00:00 evolution-calen
     1916 ?        00:00:00 unity-fallback-
     1929 ?        00:00:00 nautilus
     1933 ?        00:00:00 polkit-gnome-au
     1937 ?        00:00:01 nm-applet
     1945 ?        00:00:00 vmtoolsd
     1998 ?        00:00:00 gvfs-udisks2-vo
     2023 ?        00:00:00 gvfs-mtp-volume
     2029 ?        00:00:00 gvfs-afc-volume
     2033 ?        00:00:00 gconfd-2
     2036 ?        00:00:00 gvfs-gphoto2-vo
     2059 ?        00:00:00 gvfsd-trash
     2078 ?        00:00:00 gvfsd-burn
     2100 ?        00:00:00 gvfsd-metadata
     2105 ?        00:00:00 telepathy-indic
     2112 ?        00:00:00 mission-control
     2118 ?        00:00:00 signon-ui
     2126 ?        00:00:00 gnome-terminal
     2132 ?        00:00:00 gnome-pty-helpe
     2133 pts/1    00:00:00 bash
     2182 ?        00:00:00 zeitgeist-datah
     2187 ?        00:00:00 zeitgeist-daemo
     2193 ?        00:00:00 zeitgeist-fts
     2197 ?        00:00:00 cat
     2207 pts/1    00:00:00 ps

        第一列内容是进程标识符(PID),这个标识符是唯一的;最后一列内容是进程的程序文件名。我们可以从中间找到有多个进程对应同一个程序文件名的情况,这是因为有一些常用的程序被多次运行了,比如shell和vi编辑器等。

    注意:如果ps命令不使用“-u 用户名”作为参数,将不能检查到后台运行的进程。

    xiaomanon@xiaomanon-machine:~$ ps
      PID TTY          TIME CMD
     2133 pts/1    00:00:00 bash
     2325 pts/1    00:00:00 ps

    2 进程中重要的标识符

        每个进程都有6个重要的ID值,分别是:进程ID、父进程ID、有效用户ID、有效组ID、实际用户ID和实际组ID。这6个ID保存在内核中的数据结构中,有些时候用户程序需要得到这些ID。

        例如,在/proc文件系统中,每一个进程都拥有一个子目录,里面存有进程的信息。当使用进程读取这些文件时,应该先得到当前进程的ID才能确定进入哪一个进程的相关子目录。由于这些ID存储在内核之中,因此,Linux提供一组专门的接口函数来访问这些ID值。

        Linux环境下分别使用getpid()和getppid()函数来得到进程ID和父进程ID,分别使用getuid()和geteuid()函数来得到进程的用户ID和有效用户ID,分别使用getgid()和getegid()来获得进程的组ID和有效组ID,其函数原型如下:

    #include <unistd.h>
    pid_t getpid(void);    //获取进程ID
    pid_t getppid(void);  //获取父进程ID
    
    uid_t getuid(void);    //获取用户ID
    uid_t geteuid(void);    //获取有效用户ID
    
    gid_t getgid(void);    //获取组ID
    gid_t getegid(void);    //获取有效组ID

        以上6个函数,如果执行成功,则返回对应的ID值;失败,则返回-1。除了进程ID和父进程ID这两个值不能够更改以外,其他的4个ID值在适当的条件下可以被更改。下面的示例程序用于获取当前进程的6个ID值并打印出来。

    //Get ID information about current process
    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
        printf("PID: %u
    ", getpid());
        printf("PPID: %u
    ", getppid());
        printf("UID: %u
    ", getuid());
        printf("EUID: %u
    ", geteuid());
        printf("GID: %u
    ", getgid());
        printf("EGID: %u
    ", getegid());
    
        return 0;
    }

    程序运行效果如下:

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./getid 
    PID: 2681
    PPID: 2133
    UID: 1000
    EUID: 1000
    GID: 1000
    EGID: 1000

    3 参考文献

    [1] 吴岳,Linux C程序设计大全,清华大学出版社

  • 相关阅读:
    rstudio执行代码&注释
    Python,mac下如何安装pip、ipython
    利用MATLAB批量完成科研数据处理
    稳定性与鲁棒性区别(转)
    Matlab subs函数的用法
    matlab替换
    opencv-python(cv2)
    ConvolutionalLSTMNetwork: AMachineLearning ApproachforPrecipitationNowcasting论文笔记
    ROLO:Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking(二)
    ROLO:Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking(一)
  • 原文地址:https://www.cnblogs.com/xiaomanon/p/4195327.html
Copyright © 2011-2022 走看看