一、进程标识
OS会为每个进程分配一个唯一的整型ID,做为进程的标识号(pid)。进程除了自身的ID外,还有父进程ID(ppid),所有进程的祖先进程是同一个进程,它叫做init进程,ID为1,init进程是内核自举后的一个启动的进程。init进程负责引导系统、启动守护(后台)进程并且运行必要的程序。
虽然进程ID是唯一的,但是进程ID是可复用的。当一个进程终止后,其进程ID就成为复用的候选者。
系统中有一些专用进程,但具体细节随实现而不同。ID为0的进程通常是调度进程,常常被称为交换进程。该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程。
进程的标识号(pid)和父进程ID(ppid)可以分别通过函数getpid()和getppid()获得(返回值都是整型的)。
二、进程的用户ID与组ID(进程的运行身份)
进程在运行过程中,必须具有一类似于用户的身份,以便进行进程的权限控制,缺省情况下,哪个登录用户运行程序,该程序进程就具有该用户的身份。例如,假设当前登录用户为gotter,他运行了ls程序,则ls在运行过程中就具有gotter的身份,该ls进程的用户ID和组ID分别为gotter和gotter所属的组。这类型的ID叫做进程的真实用户ID和真实组ID。真实用户ID和真实组ID可以通过函数getuid()和getgid()获得(返回值都是整型的)。
与真实ID对应,进程还具有有效用户ID和有效组ID的属性,内核对进程的访问权限检查时,它检查的是进程的有效用户ID和有效组ID,而不是真实用户ID和真实组ID。缺省情况下(系统默认情况),用户的(有效用户ID和有效组ID)与(真实用户ID和真实组ID)是相同的。有效用户id和有效组id通过函数geteuid()和getegid()获得(返回值都是整型的)。
#include <unistd.h>
pid_t getpid() //返回值:调用进程的进程ID
pid_t getppid() //返回值:调用进程的父进程ID
uid_t getuid() //返回值:调用进程的实际用户ID
uid_t geteuid() //返回值:调用进程的有效用户ID
gid_t getgid() //返回值:调用进程的实际组ID
gid_t getegid() //返回值:调用进程的有效组ID
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("pid:%d ppid:%d\n",getpid(),getppid());
printf("uid:%d euid:%d\n",getuid(),geteuid());
printf("gid:%d egid:%d\n",getgid(),getegid());
return 0;
}
PS:用ps -elf可以查看现有进程
ps -elf | grep pidname 查看进程pid
kill -9 pidname 杀掉进程
将编译后的可执行文件的权限改为“s”(s的含义:将可执行程序的权限上升到root,比如密码的修改。在赋予s权限的时候,必须确保程序有x权限,是可执行程序,否则s权限不能生效,显示为大写的S)