进程标识
- 每个进程都有唯一的非负整数表示的进程 ID
- 虽然进程ID是唯一的,但是进程ID是可以复用的。当一个进程终止时,其进程ID就成为了服用的候选者。大多数的UNIX系统实现延时复用算法,使得赋予新建进程的ID不同于最近终止进程所使用的ID。这是为了防止将新进程误认为时使用同一ID的某个已终止的先前进程。
系统中的一些专用进程
- 交换进程/调度进程(swapper),进程ID为0。该进程是系统进程的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程。
- init进程,进程ID为1,它在自举过程结束时由内核调用.
init进程
- init进程通常读取与系统有关的初始化文件
- init进程决不会终止,它是一个普通的用户进程(与交换进程不同的是它不是内核中的系统进程),但是它以超级用户特权运行。
- init进程是所有孤儿进程的父进程。
其他标识符
下列函数返回这些标识符。
#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
函数测试
#include <stdio.h>
#include <unistd.h>
int main(){
pid_t pid;
pid_t father_id;
uid_t real_user_id;
uid_t valid_user_id;
gid_t real_group_id;
gid_t valid_group_id;
pid = getpid();
father_id = getppid();
real_user_id = getuid();
valid_user_id = geteuid();
real_group_id = getgid();
valid_group_id = getegid();
printf(" pid is :%d\n",pid);
printf(" father is %d\n",father_id);
printf(" real_user_id is %d\n",real_user_id);
printf(" valid_user_id is %d\n",valid_user_id);
printf(" real_group_id is %d\n",real_group_id);
printf("valid_group_id is %d\n",valid_group_id);
return 0;
}
执行命令:
gcc id_demo.cpp -o id_demo -g -lpthread
运行结果:
用user权限访问
可以用top查看所有的运行进程
我看到10888是一个bash进程,应该是cpp的这个进程的父进程。
关于有效用户(valid)和实际用户(real)ID区别:
- 实际用户/实际组 我们实际是谁
- 有效用户/有效组 用于文件访问权限检查
通常,有效用户ID等于实际用户ID,有效组ID等于实际组的ID
为了增强理解,我又用root权限执行了上述程序。结果如下:
user和root权限执行时的实际用户id、有效用户id都发生了变化。可以看出一般情况下确实是有效用户ID等于实际用户ID,有效组ID等于实际组的ID。(ps:我这里没有将用户进行分组,所以用户id和组id是一致的)
以上内容部分摘取自《UNIX环境高级编程 第三版》(APUE)