exce函数组和fork函数

exce函数组

(1)exec函数族说明

        fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容;exec函数族可以用来在一个进程中启动另一个可执行文件,该可执行文件将代替当前进程的执行映像(包括原调用进程的数据段、代码段和堆栈段)。该调用并没有生成新的进程,而是在原有进程的基础上,替换原有进程的正文,调用前后是同一个进程,除了进程号PID不变,其他全部被新的进程替换了。这里的可执行文件既可以是二进制文件,也可以是Linux下的任何可执行的脚本文件。

       (2)exec函数族语法

        所需头文件:

                #include <unistd.h>

        六种调用形式:

                int execl(const char *path, const char *arg, ...)

                int execv(const char *path, char *const argv[])

                int execle(const char *path, const char *arg, ..., char *const envp[])

                int execve(const char *path, char *const argv[], char *const envp[])

                int execlp(const char *file, const char *arg, ...)

                int execvp(const char *file, char *const argv[])

        函数返回值:

                -1:出错

        exec函数名对应位含义:

                前4位:均为exec

                第5位:L:参数传递为逐个列举的方式,其语法为const char *arg

                             V:参数传递为构造指针数组的方式,其语法为char *const argv[]

                第6位:E:可传递新进程环境变量

                             P:执行文件查找可以只给出文件名,系统就会自动按照环境变量"$PATH"所指定的路径进行查找

       (3)exec函数族应用举例

                 以下程序实现子进程执行可执行文件,父进程显示执行结果。

上代码

#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
	int index;
//	char *list[]={"./t2","hello","world",NULL};
	
	
	char **list;//不知道数组大小,动态分配大小				

	list=(char **)malloc((argc+1)*sizeof(char *));
	//list[0]="./t2";
	for(index=0;index<argc;index++)
	{
		list[index]=argv[index];
	}
	list[index]=NULL;	
	printf("excel pid:%d\n",getpid());
	printf("excel begin!\n");
	execvp(list[0],list);
//	execl("./t2","hello","world",NULL);
//	execvp(list[0],list);
//execlp("ls","ls","-l",NULL);

//	execl("/bin/ls","ls","-l",NULL);  //先传递路径
//	execl("./t2","hello","world",NULL);//必须以NULL结尾
	printf("excel end\n");
	return 0;
}


fork()

fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的几乎完全相同,

将要执行的下一条语句都是if(fpid<0)……
    为什么两个进程的fpid不同呢,这与fork函数的特性有关。

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID
    2)在子进程中,fork返回0
    3)如果出现错误,fork返回一个负值;

    在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,

fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

    引用一位网友的话来解释fpid的值为什么在父子进程中不同。其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id,

因为子进程没有子进程,所以其fpid0.


fork出错可能有两种原因:
    1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN
    2)系统内存不足,这时errno的值被设置为ENOMEM


    创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
    每个进程都有一个独特(互不相同)的进程标识符(process ID),可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值。

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
	printf("ok1\n");
	long int ret,retw;
	ret=(long int)fork();
	printf("oK2\n");
	if(ret==0)
	{
		printf("child\n");
		printf("iret fork :%d,pid :%d,ppid: %d\n",ret,getpid(),getppid());
		sleep(5);
	}
	else
	{
		printf("father\n");
		printf("iret fork :%d,pid :%d,ppid: %d\n",ret,getpid(),getppid());
		printf("wait...\n");
		retw=(long int)wait(NULL);
		printf("the child retw:%d\n",retw);
		printf("end...\n");
	}
	printf("%d pid exit\n",getpid());
	return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
execve函数fork函数是Unix-like操作系统中的两个重要的系统调用函数。 1. fork函数fork函数用于创建一个新的进程,它会复制当前进程(称为父进程)的所有状态,并创建一个新的进程(称为子进程)。这个函数没有参数,返回值有三种情况: - 对于父进程,返回新创建的子进程的PID(进程ID)。 - 对于子进程,返回值为0。 - 如果创建新进程失败,返回值为-1。 通过fork函数,父子进程会在执行fork函数的地方分别继续执行后续的代码。子进程和父进程共享一些资源,如代码段、数据段和打开的文件描述符等。但是,子进程会有自己独立的进程ID,并拥有自己的堆栈空间。 2. execve函数: execve函数用于执行一个新的程序。它会将当前进程的内存空间清空,并加载一个新的可执行文件到该空间中,并开始执行。execve函数有三个参数: - 第一个参数是要执行的程序路径。 - 第二个参数是一个字符串数组,表示程序的命令行参数。 - 第三个参数是一个字符串数组,表示程序的环境变量。 execve函数成功执行后,当前进程的代码段、数据段和堆栈等信息都会被新程序替换掉。因此,execve函数一般用于在一个进程中启动另一个程序。 总结: - fork函数用于创建一个新的进程,复制当前进程的状态。 - execve函数用于加载并执行一个新的程序,替换当前进程的内存空间。 这两个函数在进程间的创建和替换上起着重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值