进程控制
1、fork进程初识
1、进程创建:
#include<sys/types.h>
#include<unistd.h>
main(){
pid_t pid;
pid=fork();
if(pid<0)
printf("error in fork");
else if(pid==0)
printf("child id is :%d\n",getpid());
else
printf("parent id is :%d\n",getpid());
输出结果:
parent id is :4027
child id is :4028
分析:
fork 运行之后会产生两个进程:一个是父进程,一个是子进程;
在父进程中调用时候,他会返回两个参数:在父进程中反馈的值是子进程的id,在子进程中反馈的值是0;
所以子进程和父进程都会对fork后面的代码进行执行;
这样就打印两条内容。
父进程走的是else的分支:打印出来的事父进程的进程ID号;
子进程走的是:else if 的分支:打印出来的是子进程的进程ID号;
2、fork数据段
思考:代码会打印的结果:
#include<stdio.h>
#include<unistd.h>
int main(){
pid_t pid;
int count =0;
pid= fork();
count++;
printf("count =%d\n",count);
return 0;
}
输出结果:
count =1
count =1
结果分析:
子进程的数据空间,堆栈空间都会从父进程得到一个copy,而不是共享,
在子进程中对count进行+1的操作不会影响父进程中的count值,父进程中依旧为0;
3、vfork-进程创建
#include<stdio.h>
#include<unistd.h>
int main(void){
pid_t pid;
int count =0;
pid= vfork();
count++;
printf("count =%d\n",count);
return 0;
}
输出结果:
count =1
count =324141126
4-vfork: cxa_atexit.c:100: __new_exitfn: Assertion `l != NULL' failed.
Aborted (core dumped)
fork和vfork的区别:
1、fork:子进程拷贝父进程的数据段;
vfork:子进程与父进程共享数据段;
2、 fork:父子进程执行的次序不确定;
vfork: 子进程先运行,父进程后运行;
4、exec函数族
4-1: exec
用被执行的程序替换调用他端程序;
区别:
fork创建一个新de进程,产生一个新的PID。
exec启动一个新程序,替换原有的进程,因此进程端PID不会改变;
函数定义:
#include<unistd.h>
execl(const char * path,const char * arg1, ...);
参数:
path:被执行的程序名(含完整路径)
arg1- argn:被执行程序所需的参数,含程序名,以空函数结束( NULL或者(char *) 0 )
实例:
#include<unistd.h>
main(){
execl("/bin/ls","ls","-al","/etc/passwd",NULL);
}
结果显示:
-rw-r--r-- 1 root root 2499 Apr 22 17:02 /etc/passwd
4-2:execlp
函数定义:
#include<unistd.h>
execlp(const char * path,const char * arg1, ...);
参数:
path:被执行的程序名(含完整路径)
arg1- argn:被执行程序所需的参数,含程序名,以空函数结束( NULL或者(char *) 0 )
实例:
#include<unistd.h>
main(){
execlp("ls","ls","-al","/etc/passwd",(char *)0);
}
解释:
第一个ls表示的是:函数名
第二个ls表示:命令
显示结果:
-rw-r--r-- 1 root root 2499 Apr 22 17:02 /etc/passwd
4-3:execv
函数定义:
#include<unistd.h>
int execv(const char * path,char * const argv[])
参数:
path:被执行的程序名(含完整路径)
argv[]:被执行程序所需的命令行参数组
实例:
#include<unistd.h>
int main()
{
char * argv[]={"ls","-al","/etc/passwd",(char*)0};
execv("/bin/ls",argv);
}
输出结果:
-rw-r--r-- 1 root root 2499 Apr 22 17:02 /etc/passwd
4-3:system
函数定义:
#include<stdlib.h>
int system(const char * string);
功能:
调用fork产生的子进程,由子进程来调用 /bin/sh -c string 来执行参数string所代表的命令。
实例:
#include<stdio.h>
int main()
{
system("ls -al /etc/passwd");
}
结果如下:
-rw-r--r-- 1 root root 2499 Apr 22 17:02 /etc/passwd
4-4:wait
定义:
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int * status)
功能:
阻塞该进程,直到某个子进程退出;
实例:
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
void main()
{
pid_t pc,pr;
pc =fork();
if(pc==0)/*如果是子进程*/
{
printf("This is child with pid of %d\n",getpid());
sleep(2);/*休眠2秒*/
}
else if(pc>0)/*如果是父进程*/
{
pr=wait(NULL); //等待子进程退出
printf("i catched a child process with pid of %d\n",getpid());
}
exit(0);
}
结果显示:
This is child with pid of 17514
i catched a child process with pid of 17513