加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > C语言 > 正文

深入解读Linux进程函数fork(),vfork(),execX()

发布时间:2020-12-15 01:02:44 所属栏目:C语言 来源:网络整理
导读:本文研究的主要是Linux进程函数fork(),vfork(),execX()的相关内容,具体介绍如下。 函数fork() fork函数:创建一个新进程 1.fork()成功后,将为子进程申请PCB和用户内存空间。2.子进程会复制父进程用户空间的所有数据(代码段、数据段、BSS、堆、栈),文件描

本文研究的主要是Linux进程函数fork(),vfork(),execX()的相关内容,具体介绍如下。

函数fork()

fork函数:创建一个新进程

1.fork()成功后,将为子进程申请PCB和用户内存空间。
2.子进程会复制父进程用户空间的所有数据(代码段、数据段、BSS、堆、栈),文件描述符。
3.复制父亲进程PCB中绝大多数信息。
4.虽然子进程复制了文件描述符,而对于文件描述符相关的文件表项(struct file结构),则采用共享的方式。

一个实例:

#include <unistd.h>   //fork fuction
#include <fcntl.h>   //file operator
#include <sys/types.h>
#include <stdio.h>   
#include <stdlib.h>   //exit fuction
#include <string.h>
int main() {
  pid_t pid;
  int i=1;    
  int status;
  char *ch1="hello",*ch2="world",*ch3="IN";
  int fd;
  if ((fd=open("fork.txt",O_RDWR|O_CREAT,0644))==-1) {
   perror("not open");
   exit(EXIT_FAILURE);
  }
  if (write(fd,ch1,strlen(ch1))==-1) {   //write in fork.txt
   perror("not write");
   exit(EXIT_FAILURE);
  }
  if ((pid=fork())==-1) {
   perror("fork error"); 
   exit(EXIT_FAILURE);
  }
  else if(pid==0) {        //son process
   int i=2;           //change i
   printf("child:i=%dn",i);
   if (write(fd,ch2,strlen(ch2))==-1)
   perror("child write");
   return 0;
  }
  else {
   sleep(1);
   printf("parent:i=%dn",ch3,strlen(ch3))==-1)
   perror("child write");
   wait(&status);
   return 0;
  }
}

运行:

[root@localhost linux]# gcc -o fork fork.c 
[root@localhost linux]# ./fork 
child:i=2 
parent:i=1

可以看到在子进程中改变了i的值,然而父进程i仍为1,所以说子进程和父进程有自己的用户空间。而打开所创建的fork.txt可以得到hellowordIN,父子进程共同对一个文件操作写入的数据是不交叉覆盖的,说明父子进程共享文件偏移,一次共享文件表项。

函数vfork()

与fork()函数不同,vfork()函数在创建进程是并不复制父进程的地址空间,而是在必要的时候才申请新的存储空间,因此使得vfork()更有效率。

特别注意的是vfork()是共享父进程的代码以数据段。

一个例子:

#include <unistd.h>   //fork fuction
#include <fcntl.h>   //file operator
#include <sys/types.h>
#include <stdio.h>   
#include <stdlib.h>   //exit fuction
#include <string.h>
int i=10;
int main() {
  pid_t pid;
  if ((pid=fork())==-1) {
   perror("fork error"); 
   exit(EXIT_FAILURE);
  }
  else if(pid==0) {        //son process
   i++;
   printf("child:i=%dn",i);
   _exit(0);     
  }
  else {
   sleep(1);
   printf("parent:i=%dn",i);
   return 0;
  }
}

注意:上面的代码中回收子进程用的是_exit(0),如果用return 0;的话它会回收用户空间,因此在父进程调用的时候会出现段错误。

下面是调用输出结果:

如果以fork()创建则会输出: 
[root@localhost linux]# ./fork 
child:i=11 
parent:i=10 
如果改为vfork(),则: 
child:i=11 
parent:i=11

函数exec X()系列函数

用fork()函数创建紫禁城后,如果希望在当前子进程中运行新的程序,则可以调用execX系列函数。
注意:当进程调用exec函数后,该进程的用户空间资源完全有新程序代替。
这些函数的区别在于:

1.指示新程序的位置是路径还是文件名 
2. 在使用参数时是使用参数列表哈市使用argv[]数组 
3.后缀有l(list)表示使用参数列表,v表示使用argv[]数组

具体如下所示:

#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,.../*(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 evnp[]);

一个实例:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc,char* argv[]) {
  pid_t pid;
  if ((pid=fork())==-1)
    printf("error");
  else if (pid==0) 
    execl("/bin/ls","ls","-l",argv[1],(char *)0);
  else
    printf("father okn");
}

运行可以看到在子进程中执行了ls命令。

[yqtao@localhost linux]$ gcc -o exec execX.c
[yqtao@localhost linux]$ ./exec /home father ok

//execlp()函数使用

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc,char* argv[]) {
  execlp("ls","/home",(char*)0);
}

//execv()函数的使用

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc,char* argv[]) {
  char* argv1[]={"ls",0};
  execv("/bin/ls",argv1);
}

ecvp()会从环境变量PATH所指定的目录中查找文件名作为第一个参数,第二个及以后的参数由参数列表,注意最后一个成员必须为NULL

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc,0};
  execvp("ls",argv1);
}

总结

以上就是本文关于深入解读Linux进程函数fork(),execX()的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

您可能感兴趣的文章:

  • 浅谈Linux vfork与fork简单对比分析
  • 详解linux中fork、vfork、clone函数的区别

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读