【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
来源:互联网 发布:ubuntu 断电日志 编辑:程序博客网 时间:2024/05/22 04:29
【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
进程资源:
进程资源由两部分组成:内核空间进程资源和用户空间进程资源。
内核空间进程资源即进程控制块(PCB)相关的信息。
包括进程控制块本身、打开的文件表项、当前目录、当前终端信息、线程基本信息、可访问内存地址空间、PID、PPID、UID、EUID等。也就是说,内核通过PCB可以访问到该进程所有的资源。这些资源只能通过系统调用才能访问。这一资源在当前进程退出时,只能由另一进程来回收。
用户空间进程资源包括通过成员mm_struct映射的内存空间。
实质就是进程的代码段、数据段、堆、栈,以及可以共享访问的内存空间。这些资源进程可以直接访问。这些资源在进程退出时主动释放。在进程运行时,可以通过文件/proc/{pid}/maps来查看可以访问的地址空间。
进程状态:
进程基本属性:
与进程本身相关的属性包括进程号(PID)、父进程号(PPID)、进程组号(PGID)。
进程号:获取函数getpid(),在/usr/include/unistd.h中声明。返回值类型为pid_t, 成功返回当前进程的PID,失败返回-1,错误原因存储在error中。pid_t类型其实就是int类型的typedef,重新定义数据类型有助于提高代码的可阅读性。
父进程号:获取函数为getppid(), 成功返回当前进程的父进程号(PPID),其他与getpid()类似。
进程组号:获取函数getpgid(pid_t pid),用来获取指定进程的进程组号(PGID),如果参数为0,表示获取当前进程组号。其他与getpid()类似。也可以用getpgrp()来获取当前进程的进程组号。
系统调用函数setpgid(pid_t pid,pid_t pgid)用来将某进程加入到某个进程组。
会话:是一个或多个进程的集合。getsid(pid_t pid)用来获取某个进程的会话号SID。函数setsid()用来创建新会话。
控制终端:函数tcgetpgrp(int filedes)获取当前前台进程组的进程组号。函数tcsetpgrp(int filedes, pid_t pgrpid)设置某个进程是前台还是后台进程。函数tcgetsid(int filedes)获取控制终端的会话首进程的会话ID。、
示例程序代码(取自《Linux高级程序设计》):
/*************************************************************************> File Name: pg_test.c> Author: Geng> Mail: genglut@163.com> Created Time: Thu 30 Oct 2014 06:16:08 PM CST ************************************************************************/#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<stdlib.h>int main(){int fd;pid_t pid;pid = fork();if(pid == -1)perror("fork");else if(pid > 0){wait(NULL);exit(EXIT_FAILURE);}else {if((fd = open("/dev/pts/0", O_RDWR)) == -1)perror("fopen");printf("pid=%d, ppid=%d\n", getpid(), getppid());printf("sid=%d, tcgetsid=%d\n", getsid(getpid()), tcgetsid(fd));printf("tcgetpgrp=%d\n", tcgetpgrp(fd));printf("pigd=%d\n", getpgid(getpid()));}}
运行程序:
yang@ubuntu:~/temp$ ps PID TTY TIME CMD 3198 pts/0 00:00:02 bash 4318 pts/0 00:00:00 psyang@ubuntu:~/temp$ ./pg_test pid=4320, ppid=4319sid=3198, tcgetsid=3198tcgetpgrp=4319pigd=4319
关于进程组、会话和控制终端的文章链接:
http://www.2cto.com/os/201302/191922.html
http://blog.csdn.net/kankan231/article/details/23838711
http://blog.csdn.net/daniel_h1986/article/details/6067685
http://shake863.iteye.com/blog/187085
进程用户属性:
进程真实用户号(RUID) 获取函数:getuid()
真实用户组号(RGID) 获取函数:getgid()
有效用户号(EUID) 获取函数:geteuid()
有效用户组号(EGID) 获取函数:getegid()
其他相关函数:
getresuid(&ruid, &euid, &suid);
getresgid(&rgid, &egid, &sgid);
普通用户能够修改自己的密码的原因:
/etc/passwd文件用来存储所有用户信息,任何用户都可以修改自己的密码,显然,其它用户在执行/usr/bin/passwd命令时修改了/etc/passwd文件(并不是说可以使用vi编辑器修改),但是,通过查看/etc/passwd文件的权限,发现普通用户对此文件仅有读的权限。是什么原因导致普通用户可以修改/etc/passwd文件呢?
这是因为用户执行“/usr/bin/passwd”命令时,/usr/bin/passwd文件设置了setuid位,在执行此程序(/usr/bin/passwd)时,该用户所拥有的权限等同于文件“/usr/bin/passwd”的拥有者root的权限,而root用户拥有对/ect/passwd文件写的权限,因此普通用户可以通过/usr/bin/passwd来修改/etc/passwd文件的内容。
如果清除掉“/usr/bin/passwd”文件的setuid权限位,普通用户就不能修改自己的密码了。
示例代码:
/*************************************************************************> File Name: getid_example.c> Author: Geng> Mail: genglut@163.com> Created Time: Thu 30 Oct 2014 09:33:00 PM CST ************************************************************************/#include<stdio.h>#include<unistd.h>#include<stdlib.h>int main(int argc, char *argv[]){int pid;printf("\tuid\tgid\teuid\tegid\n");printf("parent\t%d\t%d\t%d\t%d\n", getuid(), getgid(), geteuid(), getegid());int ruid, euid, suid;int rgid, egid, sgid;getresuid(&ruid, &euid, &suid);printf("\truid\teuid\tsuid\n");printf("\t%d\t%d\t%d\n", ruid, euid, suid);getresgid(&rgid, &egid, &sgid);printf("\trgid\tegid\tsgid\n");printf("\t%d\t%d\t%d\n", rgid, egid, sgid);if((pid = fork()) < 0){perror("fork");exit(EXIT_FAILURE);}else if(pid > 0){sleep(1);}else if(pid == 0){printf("child\t%d\t%d\t%d\t%d\n", getuid(), getgid(), geteuid(), getegid());getresuid(&ruid, &euid, &suid);printf("\truid\teuid\tsuid\n");printf("\t%d\t%d\t%d\n", ruid, euid, suid);getresgid(&rgid, &egid, &sgid);printf("\trgid\tegid\tsgid\n");printf("\t%d\t%d\t%d\n", rgid, egid, sgid);}return 0;}
关于进程的实际用户ID和有效用户ID的文章链接:
http://www.cnblogs.com/kunhu/p/3699883.html
linux:SUID、SGID详解:
http://www.cnblogs.com/fhefh/archive/2011/09/20/2182155.html
原文链接:http://blog.csdn.net/geng823/article/details/40624497
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 回收进程用户/内核资源
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - Linux常见信号及处理
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 孤儿进程和僵死进程
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 守护进程
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号集与屏蔽信号
- 【原创】《Linux高级程序设计》杨宗德著- 进程管理与程序开发 - fork和vfork函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - exec和system函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 管道
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 等待信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号应用实例
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号量通信机制
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列
- 【原创】《Linux高级程序设计》(杨宗德著)--- Linux进程存储管理
- Linux高级程序进程管理
- IOS下点击按钮后退到上一个界面
- 【掌沃WiFi商盟】如何创建砸金蛋活动
- Java程序如何生成Jar、exe及安装文件
- POJ 3692 Kindergarten(最大独立集)
- 绘制球赛贝尔图
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
- Android view中的requestLayout和invalidate方法
- JVM学习笔记-本地方法栈(Native Method Stacks)
- java线程中Callable与Future
- R语言常用函数参考
- static_cast、dynamic_cast、reinterpret_cast和const_cast
- 1.2 内容综述 2.5 进程控制 2.6 linux内核对内存的使用方法
- handler 警告This Handler class should be static or leaks might occur 的回调解决方法
- poj 1816 Wild Words(字典树+DFS)