进程控制(1):进程标识符

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


1 进程标识符

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

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

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

[email protected]:~$ 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 用户名”作为参数,将不能检查到后台运行的进程。

[email protected]:~$ 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\n", getpid());
    printf("PPID: %u\n", getppid());
    printf("UID: %u\n", getuid());
    printf("EUID: %u\n", geteuid());
    printf("GID: %u\n", getgid());
    printf("EGID: %u\n", getegid());

    return 0;
}

程序运行效果如下:

[email protected]:~/Documents/c_code$ ./getid
PID: 2681
PPID: 2133
UID: 1000
EUID: 1000
GID: 1000
EGID: 1000

3 参考文献

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

时间: 2024-11-05 14:51:46

进程控制(1):进程标识符的相关文章

(转)进程控制:进程的创建、终止、阻塞、唤醒和切换

进程控制:进程的创建.终止.阻塞.唤醒和切换 进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程.撤销已有进程.实现进程状态转换等功能.在操作系统中,一般把进程控制用的程序段称为原语,原语的特点是执行期间不允许中断,它是一个不可分割的基本单位. 进程的创建 允许一个进程创建另一个进程.此时创建者称为父进程,被创建的进程称为子进程.子进程可以继承父进程所拥有的资源.当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程.此外,在撤销父进程时,也必须同时撤销其所有的子进程.

进程控制在进程管理中的作用

 进程控制是进程管理中最基本的功能.它用于创建一个新进程,终止一个已完成的进程,或者去终止一个因出现某事件而使其无法运行下去的进程,还可负责进程运行中的状态转换. 一.创建进程 1.引起创建进程的事件 在多道程序环境中,只有(作为)进程(时)才能在系统中运行.因此,为使程序能运行,就必须为它创建进程.导致一个进程去创建另一个进程的典型事件,可以有以下四类: 1) 用户登录 在分时系统中,用户在终端键入登录命令后,如果是合法用户,系统将为该终端建立一个进程,并把它插入到就绪队列中. 2)作业调

进程控制(二)---进程标识符

Linux操作系统中为了区分每一个进程,为每个进程分配一个唯一的进程号,也称为进程ID.进程 ID 是保存在进程的 PCB 中,属于进程的内核资源. 每个进程的进程 ID 虽然是唯一的,但是进程 ID 是可以重用的,当一个进程被终止时,其所有的资源将会被释放,也包括进程 ID.当系统再次创建一个新的进程时,可以为其分配已经被释放的进程 ID .由于操作系统采用延迟重用算法,所以为刚创建的进程分配的进程 ID通常不会是刚被释放的进程 ID . 操作系统中有些进程的进程 ID 是固定的,比如 调度进

进程控制(2): 进程操作

进程是系统中基本的执行单位,本节将介绍基本的进程控制原语,包括进程的创建与退出,以及设置除进程标识符(PID)以外的其他标识符. 1 创建进程 Linux系统允许任何一个用户进程创建一个子进程,创建成功后,子进程存在于系统之中,并且独立于父进程.该子进程可以接受系统调度,可以得到分配的系统资源.系统也可以检测到子进程的存在,并且赋予它与父进程同样的权利. Linux系统下使用fork()函数创建一个子进程,其函数原型如下: #include <unistd.h> pid_t fork(void

进程控制(Note for apue and csapp)

1. Introduction We now turn to the process control provided by the UNIX System. This includes the creation of new processes, program execution, and process termination. We also look at the various IDs that are the property of the process - real, effe

Linux进程控制程序设计

一.进程控制理论基础 进程:是一个具有一定独立功能的程序的一次运行活动.程序是静态的,程序在运行的时候是进程. 1.进程的特点: 动态性:区别于程序的显著特性 并发性:多个进程可以同时执行 独立性:独立的 异步性:进程与进程之间可以进行异步操作 2.进程三态: 进程的ID(PID):标志进程的唯一数字. 父进程ID(PPID) 启动进程的用户ID(UID) 3.进程互斥 进程互斥是指当有若干进程都要使用某一共享资源时,任何时刻最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占用该资源者

小何讲进程: Linux进程控制编程 (fork、vfork)

所谓进程控制,就是系统使用一些具有特定功能的程序段来创建进程.撤消进程以及完成进程在各种状态之间的转换, 从而达到多进程高效率并发执行和协调资源共享的目的.进程控制是进程管理和处理机管理的一个重要任务. 1. fork()创建进程 在Linux系统中,除了系统启动之后的第一个进程(根进程)由系统来创建外, 其余所有进程都必须由已存在的进程来创建新创建的进程叫子进程,而创建子进程的进程叫父进程, 具有相同父进程的进程叫兄弟进程. 在Linux中创建一个新进程的方法是使用fork()函数. fork

进程控制概念简介 多线程上篇(三)

进程控制 进程的基本数据信息是操作系统控制管理进程的数据集合,这些信息就是用来控制进程的,此处我们说的进程控制就是进程的管理. 比如进程有状态,那么进程的创建.终止,状态的切换,这都不是进程自主进行的,都是通过操作系统进行管理的 如下图所示,所有的相关数据都是操作系统用来管理维护进程的 操作系统抽象出进程概念的核心是为了运行程序 所以进程的执行态是最为核心的 其他的状态则是为了更好的控制管理进程以及进程的并发执行而附加的 所以,一定程度上来讲,操作系统对于进程的控制,可以认为是对于进程的不同状态

进程控制(二)与linux下的自有服务

一.进程动态信息查看top 第一部分 统计信息 [[email protected] ~]# top top - 19:22:52 up 1:32, 2 users, load average: 0.00, 0.00, 0.00 Tasks: 106 total, 1 running, 105 sleeping, 0 stopped, 0 zombie Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 99.6%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%st

UNIX高级环境编程(11)进程控制(Process Control)- 进程快照,用户标识符,进程调度

1 进程快照(Process Accounting) 当一个进程终止时,内核会为该进程保存一些数据,包括命令的小部分二进制数据.CPU time.启动时间.用户Id和组Id.这样的过程称为process accounting,本篇译为进程快照. 函数acct可以打开或关闭进程快照功能. 负责记录快照的数据结构如下所示: 成员说明: ac_flag成员记录进程执行过程中的特定事件(稍后的表中会详细说明): 进程创建时,初始化进程快照的数据在进程表(process table)中,但是只有在进程终止