apue学习第十四天——进程控制3

这几天进度实在是有点慢(摇摇头~~),好啦,今天把第八章剩下的内容都搞定吧!


exec族(这里用了个族,包括七个函数)怎么工作呢?我们来看看:

The exec() family of functions replaces the current process image with a new process image. (一语中的)

比如说fork了一个子进程,开辟了一个新的空间,然后,我们在子进程(if(pid == 0){ ... })中执行exec。这个时候,exec在不创建新进程(ID当然也不会变)的情况下,调用一个新的程序,从新程序的main开始执行,替换了当前这个子进程的.text, .data, .bss, heap, stack。懂了吧~

具体有哪7个exec函数呢?我们先看定义;在定义之后,把他们的关系图也贴出来,一目了然;最后给出一段代码示例:

#include <unistd.h>
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ...
/* (char *)0, char *const envp[] */ );
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );
int execvp(const char *filename, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);
/*All seven return: −1 on error, no return on success*/
它们有什么区别呢?

(1) 注意它们7个的第一个argument,前四个是pathname,接下来两个是filename(*p),最后一个是fd(f*);

(2) 注意参数表的传递,l(list), v(vector);

(3) 以e结尾的3个函数(environment),可以传递一个环境指针(char **或char * [])。


细节就不说了,看关系图:


看它们,只有execve是system call,其他6个都是library function。exec执行前后real user ID不变,effective user ID取决于它们所执行程序文件的set user ID。(group ID类似)

最后看代码:

#include "apue.h"
#include <sys/wait.h>

char *env_init[] = {"USER=unkown", "PATH=/tmp", NULL};

int main(void)
{
	pid_t pid;

	if((pid = fork()) < 0)
	{
		err_sys("fork error");
	} else if (pid == 0)	/*special pathname, special environment*/
	{
		if(execle("/home/liuzch/workspace/echoall", "echoall", "myarg1", "MY ARG2", (char *)0, env_init) < 0)
			err_sys("execle error");
	}

	if(waitpid(pid, NULL, 0) < 0)
		err_sys("wait error");

	if((pid = fork()) < 0) {
		err_sys("fork error");
	} else if (pid == 0) {	/*special filename, inherit environment*/
		if (execl("/home/liuzch/workspace/interp", "interp", "only 1 arg", (char *)0) < 0)
			err_sys("execlp error");
	}

	exit(0);
}

代码注意以下几点:

(1)echoall是输出参数的c文件编译后,将a.out重命名得到的;interp是interpreter file,解释器文件和解释器的解释看这里:http://blog.csdn.net/shiquxinkong/article/details/10228609;

(2)第一个fork之后的execle的实现;

(3)第二个fork之后execl的实现,第一个参数指向了file descriptor,它的内容是

#!/home/liuzch/workspace/echoall fromInterp

那么最终输出的时候,argv[0]=/home/liuzch/workspace/echoall; argv[1]=fromInterp; argv[2]=/home/liuzch/workspace/interp(其后依次是execl中的argv)。(我跑的时候一直显示permission denied,为什么呢?The initial argument for these functions is the pathname of a file which is to be executed.所以说echoall是可执行的,interp也必须是可执行的。既然permission denied,那么把interp文件改成可执行的就可以啦!)


接下来8.11之后的内容简单记录一下提纲,用到再查:

8.11 changing user IDs and group IDs

8.13 system function:ISO C 定义,对操作系统依赖性很强,用于调用shell中的命令,具体用法man一下即可。

8.14 accounting process:进程终止时写一个account 记录。

8.16 进程调度:每个进程有个nice值,nice值越小,优先级越高。


下面是长长的分割线

————————————————————————————————————————————————————————

第八章结束,主要介绍了进程的fork,exit,waitpid和exec,很经典,期待第九章~







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值