一: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时:输出我们当前执行进程的环境变量。
阅读(1858) | 评论(0) | 转发(0) |