您的位置:首页 > 其它

fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结

2015-08-04 21:07 495 查看
一:fork()和vfork()的区别:

fork()函数可以创建子进程,有两个返回值,即调用一次返回两个值,一个是父进程调用fork()后的返回值,该返回值是刚刚创建的子进程的ID;另一个是子进程调用fork()后的返回值,该返回值为0。

vfork与fork不同的地方在于:

使用fork()创建子进程时:子进程只是完全复制父进程的资源,并且哪个进程先运行取决于系统的调度算法。



点击(此处)折叠或打开






int globVar = 5;





int main(int argc,char *argv[])




{




int var = 1,i;




pid_t pid;









printf("fork is different with vfork\n");









pid = fork();




// pid = vfork();




printf("%d---------\n",pid);




switch(pid)




{




case 0:




i = 2;




while(i-- > 0)




{




printf("--------Child process is running\n");




globVar++;




var++;




printf("--------c sleep\n");




sleep(1);




}




printf("--------Clild's globVar = %d,var = %d\n",globVar,var);




break;




case -1:




perror("Process creat faild\n");




exit(0);




default:




i = 3;




while(i-- > 0)




{




printf("Parent process is running\n");




globVar++;




var++;




printf("p sleep\n");




sleep(1);









}




printf("Parent's globVar = %d,var = %d\n",globVar,var);




exit(0);




}




}



















fork is different with vfork




14070---------




Parent process is running




p sleep




0---------




--------Child process is running




--------c sleep




Parent process is running




p sleep




--------Child process is running




--------c sleep




Parent process is running




p sleep




--------Clild's globVar = 7,var = 3




Parent's globVar = 8,var = 4





使用vfork()创建子进程时:操作系统并不将父进程的地址空间完全复制到子进程,子进程共享父进程的地址空间,并且保证子进程先运行。



点击(此处)折叠或打开






将上面的例子vfork()注释去掉,而将fork();注释掉,可以得到与之不同的结果










fork is different with vfork




0---------




--------Child process is running




--------c sleep




--------Child process is running




--------c sleep




--------Clild's globVar = 7,var = 3




14160---------




Parent process is running




p sleep




Parent process is running




p sleep




Parent process is running




p sleep




Parent's globVar = 10,var = 32714





二:signal函数,可以用来处理我们系统的一些信号。

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler));

函数的第一个参数指定该信号的值,第二个参数指定对该信号的处理。可以忽略该信号。参数设为(SIG_ING),也可以采用系统默认的方式,参数设置为(SIG_DFL),下面的例子就是忽略我们的输入信号。



点击(此处)折叠或打开






#include<stdio.h>




#include<signal.h>




int main(int argc ,char *argv[])




{




signal(SIGINT,SIG_IGN);




for(;;);




return 0;




}







执行结果就是无限循环,我们ctrl+c也无法停止。

三:exec系列函数(execl,execlp,execle,execv,execvp)函数用法总结:

exec系列函数均可以把当前进程替换成一个新进程,保持原有的pid不变。对于以上函数,我按照自己的理解分为三类,当然这不一定是最好的方法,具体看自己了。

1:execl和execlp:我们给它传入相应命令和参数,它就可以脱离当前进程而独立出来。他们两个的不同在于第一个参数传绝对路径还是相对路径,请看下面例子:



点击(此处)折叠或打开






#include<stdio.h>




#include<stdlib.h>




#include<unistd.h>




int main(int argc,char *argv[])




{




printf("entering main process----\n");




// execl("/bin/ls","ls","-l","/home",NULL);




// execlp("ls","ls","-l","/home",NULL);









printf("exiting main process -----\n");









return 0;




}





程序的执行结果就是我/home中的内容了,而第10行的内容并不会被打印出来。有没有懂一点点呢,继续;

2:execv和execvp函数:同样,后面有p就是它可以只传入文件名或者命令名就可以执行,不过它的参数可以自己用argv[]传进去。



点击(此处)折叠或打开






int ret;









printf("entering main process----\n");




char *argv[] = {"ls","-l","/home",NULL};




// ret = execv("/bin/ls",argv);




ret = execvp("ls",argv);




if(ret == -1)




{




perror("execvp error");




}




printf("exiting main process-----\n");




return 0;





看吧,主要是execv和execvp只能传入两个参数,所以把其他的东西就放在argv[]中了,执行成功返回0,失败返回-1。

3:execle函数,可以获得环境变量,看下面例子:

(注意:test_execle_child 是一个可以打印当前环境变量的函数)

test_execle_child函数如下:



点击(此处)折叠或打开






extern char ** environ;









int main(int argc,char *argv[])




{




int i ;









printf("\n\n现在已经进入main函数中的子程序---- pid=%d\n",getpid());




sleep(2);




for(i = 0;environ[i] != NULL;i++)




{




printf("%s\n",environ[i]);




}




return 0;









}












点击(此处)折叠或打开






int ret;




char * const envp[] = {"aa=11","bb=22","cc=33",NULL};









printf("entering main process----\n");




// ret = execl("./test_execle_child","test_execle_child",NULL);




ret = execle("./test_execle_child","test_execle_child",NULL,envp);




if(ret == -1)




{




perror("execle error");




}




printf("exiting main process-----\n");




return 0;





当函数是execle时:输出我们envp中传进去的环境变量,

当函数时execl时:输出我们当前执行进程的环境变量。






window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];


阅读(1) | 评论(0) | 转发(0) |



0
上一篇:RedHat 7.0 下 FTP 服务的安装,启动,配置,以及虚拟用户的建立

下一篇:linux top 命令详解




相关热门文章

linux 常见服务端口

【ROOTFS搭建】busybox的httpd...

xmanager 2.0 for linux配置

什么是shell

linux socket的bug??



linux dhcp peizhi roc

关于Unix文件的软链接

求教这个命令什么意思,我是新...

sed -e "/grep/d" 是什么意思...

谁能够帮我解决LINUX 2.6 10...








给主人留下些什么吧!~~






评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: