1、进程控制

进程控制

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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值