本文研究的主要是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=%d\n",i); if (write(fd,ch2,strlen(ch2))==-1) perror("child write"); return 0; } else { sleep(1); printf("parent:i=%d\n",i); if (write(fd,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=%d\n",i); _exit(0); } else { sleep(1); printf("parent:i=%d\n",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,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 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 ok\n"); }
运行可以看到在子进程中执行了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","ls","-l","/home",(char*)0); }
//execv()函数的使用
#include <unistd.h> #include <stdio.h> #include <sys/types.h> int main(int argc ,char* argv[]) { char* argv1[]={"ls","-l","/home",0}; execv("/bin/ls",argv1); }
ecvp()会从环境变量PATH所指定的目录中查找文件名作为第一个参数,第二个及以后的参数由参数列表,注意最后一个成员必须为NULL
#include <unistd.h> #include <stdio.h> #include <sys/types.h> int main(int argc ,char* argv[]) { char* argv1[]={"ls","-l","/home",0}; execvp("ls",argv1); }
总结
以上就是本文关于深入解读Linux进程函数fork(),vfork(),execX()的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 杨千嬅《如果大家都拥有海》寰亚 [WAV+CUE][998M]
- 孟庭苇.1994-1990-1994钻石精选集2CD(2022环球XRCD限量版)【上华】【WAV+CUE】
- 群星.1998-华纳好情歌精选17首【华纳】【WAV+CUE】
- 张敬轩王菀之.2006-903.ID.CLUB拉阔演奏厅LIVE.2CD【环球】【WAV+CUE】
- 《欢欣森活》存档方法
- 《炉石传说》2024新赛季上线更新内容问题汇总
- 《南瓜恐慌》进不去游戏解决方法
- 杨烁《杨烁唱唐诗》2024Hi-Res[WAV分轨]
- 杨烁《杨烁唱唐诗》2024Hi-Res[WAV分轨]
- 童丽《民歌童丽(HQCD)》【WAV+CUE】
- 童丽《绝对收藏》2022头版限量编号[WAV+CUE][1G]
- 腾格尔《出走天堂》MQA-UHQCD限量版[低速原抓WAV+CUE][1G]
- 田震《时光音乐会》纯银CD[低速原抓WAV+CUE][1G]
- 炉石传说11月初最强登顶卡组合集 炉石传说11月初登顶卡组分享
- lol炼金龙魂详细属性是什么 2024炼金龙魂详细属性介绍