6. 利用/proc文件系统,选择一个进程,如-bash,列出并解释/proc/$PID/cmdline,
/proc/$PID/stat, /proc/$PID/status文件的内容。
实验报告:
实验名称: 实验日期: 实验设备号: 实验目的:
实验步骤:(完成实验要求的工作,需列出执行命令和执行结果,并有相关分析和解释。) 认识和体会:
实验五
实验名称:
进程管理
实验目的:
1. 进一步学习进程的属性 2. 学习进程管理的系统调用
3. 掌握使用系统调用获取进程的属性、创建进程、实现进程控制等 4. 掌握进程管理的基本原理
实验时间
6学时
预备知识:
1. 进程属性
1.1 getpid(取得进程ID)
表头文件 #include
函数说明 getpid()用来取得目前进程的进程ID,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。 返回值 目前进程的进程ID 范例
1.2 getppid(取得父进程的进程ID)
表头文件 #include
函数说明 getppid()用来取得目前进程的父进程ID。 返回值 目前进程的父进程ID。 1.3 getegid(取得有效的组ID)
表头文件 #include
定义函数 gid_t getegid(void);
函数说明 getegid()用来取得执行目前进程有效组ID。有效的组ID用来决定进程执行时组的权限。返回值返回有效的组ID。 1.4 geteuid(取得有效的用户ID)
表头文件 #include
函数说明 geteuid()用来取得执行目前进程有效的用户ID。有效的用户ID用来决定进程执行的权限,借由此改变此值,进程可以获得额外的权限。倘若执行文件的setID位已被设置,该文件执行时,其进程的euid值便会设成该文件所有者的uid。 返回值 返回有效的用户ID。 1.5 getgid(取得真实的组ID)
表头文件 #include
函数说明 getgid()用来取得执行目前进程的组ID。 返回值 返回组ID
1.6 getuid(取得真实的用户ID)
表头文件 #include
函数说明 getuid()用来取得执行目前进程的用户ID。 返回值 用户ID
1.7 times (取得进程相关的时间)
表头文件 #include
clock_t tms_utime;
/*进程花在执行用户模式代码上的时间*/
}
clock_t tms_stime; clock_t tms_cutime; clock_t tms_cstime;
/*进程花在执行内核代码上的时间*/ /*子进程花在执行用户模式代码上的时间*/ /*子进程花在执行内核代码上的时间*/
返回值 自系统自举后经过的时钟嘀嗒数。
注意 时钟嘀嗒数time转换为用户可读的方式,即多少秒,需通过如下方式:
(float)time/sysconf(_SC_CLK_TCK);
2. 进程创建
2.1 system(执行shell 命令)
表头文件 #include
定义函数 int system(const char * string);
函数说明 system()会调用fork()产生子进程,由子进程来调用/bin/sh -c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。
返回值 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。 2.2 fork(建立一个新的进程)
表头文件 #include
函数说明 fork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。Linux 使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。
注意 Linux不保证子进程会比父进程先执行或晚执行,因此编写程序时要留意死锁或竞争条件的发生。
返回值 如果fork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。如果fork 失败则直接返回-1,失败原因存于errno中。
错误代码 EAGAIN 内存不足。ENOMEM 内存不足,无法配置核心所需的数据结构空间。
exec函数簇
表头文件 #include
2.3.1 execl(执行文件)
定义函数 int execl(const char * path,const char * arg,....);
函数说明 execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]??,最后一个参数必须用空指针(NULL)作结束。 返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
范例 #include
execl(―/bin/ls‖,‖ls‖,‖-al‖,‖/etc/passwd‖,(char * )0); }
2.3.2 execlp(从PATH 环境变量中查找文件并执行)
定义函数 int execlp(const char * file,const char * arg,??);
函数说明 execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]??,最后一个参数必须用空指针(NULL)作结束。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
错误代码 参考execve()。
范例 /* 执行ls -al /etc/passwd execlp()会依PATH 变量中的/bin找到/bin/ls */ #include
execlp(―ls‖,‖ls‖,‖-al‖,‖/etc/passwd‖,(char *)0); }
2.3.3 execv(执行文件)
定义函数 int execv (const char * path, char * const argv[ ]);
函数说明 execv()用来执行参数path字符串所代表的文件路径,与execl()不同的地方在