Linux进程控制(一)
1. Linux进程概述
进程是一个程序一次执行的过程,它和程序有本质区别。程序是静态的,它是一些保存在磁盘上的指令的有序集合;而进程是一个动态的概念,它是一个运行着的程序,包含了进程的动态创建、调度和消亡的过程,是Linux的基本调度单位。那么从系统的角度看如何描述并表示它的变化呢?在这里,是通过进程控制块(PCB)来描述的。进程控制块包含了进程的描述信息、控制信息以及资源信息,它是进程的一个静态描述。
内核使用进程来控制对CPU和其他系统资源的访问,并且使用进程来决定在CPU上运行哪个程序,运行多久以及采用什么特性运行它。内核的调度器负责在所有的进程间分配CPU执行时间,称为时间片(time slice),它轮流在每个进程分得的时间片用完后从进程那里抢回控制权。
1.1. 进程标识
OS会为每个进程分配一个唯一的整型ID,做为进程的标识号(pid)。进程除了自身的ID外,还有父进程ID(ppid),所有进程的祖先进程是同一个进程,它叫做init进程,ID为1,init进程是内核自举后的一个启动的进程。init进程负责引导系统、启动守护(后台)进程并且运行必要的程序。
进程的pid和ppid可以分别通过函数getpid()和getppid()获得。
示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("pid:%d ppid:%d\n",getpid(),getppid());
return 0;
}
1.2. 进程的用户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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("uid:%d gid:%d euid:%d egid:%d\n",getuid(),getgid(),geteuid(),getegid());
return 0;
}
shell>id
uid=500(ghaha) gid=500(ghaha) groups=500(ghaha)
编译生成可执行文件a.out,程序文件的属性可能为:
-rwxrwxr-x 1 ghaha ghaha 12132 Oct 7 09:26 a.out
执行结果可能为:
shell>./a.out
uid:500 gid:500 euid:500 egid:500
现在将a.out的所有者可执行属性改为s
shell>chmod u+s a.out
shell>ll
-rwsrwxr-x 1 ghaha ghaha 12132 Oct 7 09:26 a.out
此时改另外一个用户gotter登录并运行程序a.out
shell>id
uid=502(gotter) gid=502(gotter) groups=502(gotter)
shell>./a.out
uid:502 gid:502 euid:500 egid:502
可以看到,进程的有效用户身份变为了ghaha,而不是gotter了,这是因为文件a.out的访问权限的所有者可执行为设置了s的属性,设置了该属性以后,用户运行a.out时,a.out进程的有效用户身份将不再是运行a.out的用户,而是a.out文件的所有者。
s权限最常见的例子是
/usr/bin/passwd程序,它的权限位为
shell>ll /usr/bin/passwd
-r-s--x--x 1 root root 16336 Feb 13 2003 /usr/bin/passwd
我们知道,用户的用户名和密码是保存在/etc/passwd(后来专门将密码保存在/etc/shadow,它是根据/etc/passwd文件来生成/etc/shadow的,它把所有口令从/etc/passwd中移到了/etc/shadow中。这里用到的是影子口令,它将口令文件分成两部分:/etc/passwd和/etc/shadow,此时/etc/shadow就是影子口令文件,它保存的是加密的口令,而/etc/passwd中的密码全部变成x)下的。通过ls –l查看/etc/passwd这个文件,你会发现,这个文件普通用户都没有可写的权限,那我们执行passwd的时候确实能够修改密码,那么这是怎么回事呢?也就是说,任何一个用户运行该程序时,该程序的有效身份都将是root(用普通身份去执行这个操作的时候,它会暂时得到文件拥有者root的权限),而这样passwd程序才有权限读取/etc/passwd文件的信息。
我们也来实现以下passwd的功能,实现步骤如下:
1. 用touch创建一个a.txt输入内容“hello” 类似于/etc/passwd
2. 写一个程序1.c如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
printf("uid : %d gid : %d\n", getuid(), getgid());
printf("eudi: %d egid: %d\n", geteuid(), getegid());
FILE* fp = fopen("a.txt", "a");//注意这里是以追加形式打开,说明a.txt要具有可写权限
if(fp == NULL)
{
perror("fopen error");
exit(-1);
}
fputs("world", fp);
fclose(fp);
return 0;
}
3. 编译gcc –o 1 1.c生成可执行程序1 此时1类似于/usr/bin/passwd文件
4. 用ll查看a.txt发现权限是-rw-r—r—的权限(跟/etc/passwd权限一样),说明普通用户没有可写权限,如果直接切换到普通用户执行./1会报错。
5. 用root身份将1的权限修改为-rwsr-xr-x (操作命令:chmod u+s 1,此时跟/usr/bin/passwd的权限一样),此时再切换到普通用户wangxiao,执行./1发现可以执行成功,因为此时./1进程的有效用户id变成root了,也就是说普通用户是借助root身份来实现的。
1.3. 进程的状态
进程是程序的执行过程,根据它的生命周期可以划分成3种状态。
l 执行态:该进程正在运行,即进程正在占用CPU。
l 就绪态:进程已经具备执行的一切条件,正在等待分配CPU的处理时间片。
l 等待态:进程不能使用CPU,若等待事件发生(等待的资源分配到)则可将其唤醒。
![]() |
1.4. Linux下的进程结构
Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。也就是说,进程之间是分离的任务,拥有各自的权利和责任。其中,每个进程都运行在各自独立的虚拟地址空间,因此,即使一个进程发生了异常,它也不会影响到系统的其他进程。
Linux中的进程包含3个段,分别为“数据段”、“代码段”和“堆栈段”。
· “数据段”放全局变量、常数以及动态数据分配的数据空间。数据段分成普通数据段(包括可读可写/只读数据段,存放静态初始化的全局变量或常量)、BSS数据段(存放未初始化的全局变量)以及堆(存放动态分配的数据)。
· “代码段”存放的是程序代码的数据。
· “堆栈段”存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。
![]() |

1.5. Linux下的进程管理
启动进程:手工启动 调度启动

备注:
进程process:是os的最小单元 os会为每个进程分配大小为4g的虚拟内存空间,其中 1g给内核空间 3g给用户空间{代码区数据区 堆栈区}
ps查看活动进程 ps –aux查看所有的进程 ps -aux| grep 'aa'查找指定(aa)进程 ps –ef可以显示父子进程关系 top显示前20条进程,动态的改变 pgrep 'vi'查找进程
进程状态:执行 就绪 等待状态
ps -aux看%cpu(cpu使用量) %mem(内存使用量) stat状态{S睡眠 T暂停 R运行 Z僵尸}
vi a.c &(&表示后台运行),一个死循环,按ctrl+z可以把进程暂停,再执行[bg作业ID]可以将该进程带入后台。利用jobs可以查看后台任务,fg 1把后台任务带到前台,这里的1表示作业ID
kill -9 进程号è表示向某个进程发送9号信号,从而杀掉某个进程 利用pkill a可以杀死进程名为a的进程
Linux进程控制(一)的更多相关文章
- Linux进程控制(二)
1. 进程的创建 Linux下有四类创建子进程的函数:system(),fork(),exec*(),popen() 1.1. system函数 原型: #include <stdlib.h&g ...
- Linux - 进程控制 代码(C)
进程控制 代码(C) 本文地址:http://blog.csdn.net/caroline_wendy 输出进程ID.getpid(). 代码: /*By C.L.Wang * Eclipse CDT ...
- Linux 进程控制
分享知乎上看到的一句话,共勉: 学习周期分为学习,思考,实践,校正四个阶段,周期越短,学习效率越高. 前面讲的都是操作系统如何管理进程,接下来,看看用户如何进行进程控制. 1.进程创建 先介绍一下函数 ...
- Linux进程控制(三)
1. 进程间打开文件的继承 1.1. 用fork继承打开的文件 fork以后的子进程自动继承了父进程的打开的文件,继承以后,父进程关闭打开的文件不会对子进程造成影响. 示例: #include < ...
- Linux进程控制——exec函数族
原文:http://www.cnblogs.com/hnrainll/archive/2011/07/23/2114854.html 1.简介 在Linux中,并不存在exec()函数,exec指的是 ...
- LINUX进程控制
1. 引言 一个程序是存储在文件中的机器指令序列.一般它是由编译器将源代码编译成二进制格式的代码.运行一个程序意味着将这个机器指令序列载入内存然后让处理器(cpu)逐条执行这些指令. 在Unix术语中 ...
- linux进程控制命令
& 加在一个命令的最后,可以把这个命令放到后台执行 ,如gftp &. ctrl + z 可以将一个正在前台执行的命令放到后台,并且处于暂停状态,不可执行. jobs 查看当前有多少在 ...
- linux 进程控制笔记
进程创建 普通函数调用完成后,最多返回(return)一次,但fork/vfork会返回二次,一次返回给父进程,一次返回给子进程 父进程的返回值为子进程的进程ID,子进程的返回值为0 1.pid_t ...
- linux进程控制开发实例
fork.c #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include < ...
随机推荐
- ios 编码转换 保存文件
- (NSString *)SaveFileToDocuments:(NSString *)url { // NSString *url = @"http://172.28.250.70/a ...
- 本地搭建Dubbo监控中心的安装步骤
Dubbo监控中心的安装步骤 参考链接:http://blog.csdn.net/lichunan/article/details/40349645 一.从github上下载dubbo源码进行编译: ...
- ASP.NET MVC 从IHttp到页面输出
MVCHandler应该算是MVC真正开始的地方.MVCHandler实现了IHttpHandler接口,ProcessRequest便是方法入口. MVCHandler : IHttpHandler ...
- rm删除命令
linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有 ...
- SQL技术内幕-8 使用WITH AS提高性能简化嵌套SQL
--本文来源:http://www.cnblogs.com/fygh/archive/2011/08/31/2160266.html 一.WITH AS的含义 WITH AS短语,也叫做子查询部分(s ...
- 重载和覆盖的区别?(overload vs override)
override与overload的区别? override 表示重写,overload 表示重载.override是子类和父类之间的关系,是垂直关系:overload是同一个类中方法之间的关系,是水 ...
- HDU 1142 A Walk Through the Forest(SPFA+记忆化搜索DFS)
题目链接 题意 :办公室编号为1,家编号为2,问从办公室到家有多少条路径,当然路径要短,从A走到B的条件是,A到家比B到家要远,所以可以从A走向B . 思路 : 先以终点为起点求最短路,然后记忆化搜索 ...
- junit中的assert方法总结
junit中的assert方法全部放在Assert类中,总结一下junit类中assert方法的分类.1.assertTrue/False([String message,]boolean condi ...
- 叠罗汉III之推箱子
有一堆箱子,每个箱子宽为wi,长为di,高为hi,现在需要将箱子都堆起来,而且为了使堆起来的箱子不到,上面的箱子的宽度和长度必须小于下面的箱子.请实现一个方法,求出能堆出的最高的高度,这里的高度即堆起 ...
- P2P通信标准协议(一)之STUN
前一段时间在P2P通信原理与实现中介绍了P2P打洞的基本原理和方法,我们可以根据其原理为自己的网络程序设计一套通信规则, 当然如果这套程序只有自己在使用是没什么问题的.可是在现实生活中,我们的程序往往 ...

