Monday 2 November 2015

C process,fork() and execve()

1.fork()函数    作用:在一个进程下生成它的子进程。     当进程pid为0的时候代表当前进程为子进程,大于0则是父进程,小于0代表出错。     使用:     main()     {          pid_t fpid;          fpid=fork();     }
     在语句fpid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了.为什么两个进程的fpid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;
     解释fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.    fork出错可能有两种原因:    1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。    2)系统内存不足,这时errno的值被设置为ENOMEM。


  参考博客: http://blog.csdn.net/jason314/article/details/5640969




2.exec函数    作用:代码替换:根据文件名找到可执行文件,并用此文件来取代要调用的内容(shell脚本或者C文件)。通常是用fork()函数创建子进程后,子进程调用exec函数以执行另一个程序。   解释:当进程调用exec函数时,该进程完全有新程序代换,而新程序则从其main函数开始执行。 因为调用exec并不创建新进程,所以前后进程ID并不改变。只是用一个新程序替换了当前进程的征文,数据,堆和栈段。  exec其实是一个函数组,其中真正属于系统调用的函数只有   int execve(const char* path, char *const argv[], char *const envp[]);其余都是为了方便而设置的衍生的函数。 参数说明: 例如,我们要执行一个shell脚本文件,里面的执行代码为:cat /etc/passwd 通过which cat可知,cat的输出路径为bin/cat, *argv[]={"cat", "etc/passwd",NULL},*env[]={"PATH","bin","SHELL=bash",NULL},所以:execve("bin/cat",argv,env).(注意char型都以NULL结尾。)

No comments:

Post a Comment