c 理解创建多进程

下面的程序是创建n个打印进程

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <wait.h>


int main(void){
	int t=0;
    while(1){    //循环一次,父进程创建一新进程
		
		pid_t pid=fork();    //从这句后就是主程序创建一新进程,每个线程pid值选择自己执行的代码
		if(pid==0){     //子进程     
			while(1){
		
			printf("%d:%d\n",getpid(),t);
			t++;
			sleep(1);
			}	
			
		}else{          //父进程
			sleep(5);
		}
	}
}

在这个程序的基础上就会理解服务器的并行接收客户端的原理了,这种属于批量创建新进程,每个新进程执行相同的代码。

采用多进程的并发服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>


int main(void){
	struct sockaddr_in serv,*p;
	memset(&serv,0,sizeof(serv));
	p=&serv;
	p->sin_family=AF_INET;
	p->sin_addr.s_addr=htonl(INADDR_ANY);
	p->sin_port=htons(3000);
	
	int sk=socket(PF_INET,SOCK_STREAM,0);
	if(sk==-1){
		puts("socket error\n");
		exit(1);
	}
	
	int opt=1;
	setsockopt(sk,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); //服务器地址复用
	
	if(bind(sk,(struct sockaddr*)&serv,sizeof(serv))==-1){
		puts("bind error\n");
		exit(1);
	}

	if(listen(sk,10)==-1){
		puts("listen error\n");
		exit(1);
	}
	puts("listening port\n");
	int n=0;
	
	while(n<50){
	    pid_t pid=fork();     //父进程创建子进程,新进程数控制50个
		if(pid==0){
			while(1){
			int ck=accept(sk,NULL,NULL);
			if(ck==-1){
				puts("accept error\n");
				exit(1);
			}
			//-----------------------------------------------------------------
			int t=0;       //发送一个自增数到客户端
			while(1){
				write(ck,&t,sizeof(t));
				sleep(1);       //暂停1秒
				t++;
			}
			}
			
		}else{      //父进程不执行代码,直接跳到accept状态
			n++;
		}
	
		
	}
	while(1){    //父进程产生50个新进程后循环等待,防止主程序退出,中止产生的新进程中止运行
		;
	}
	
	return 0;
}

	
	
	
	

 此程序一次产生50个accept新进程,所以可以同时接收50个客户端的接入。此程序未加入新进程的退出机制。

加入子进程退出机制的多进程并发服务器


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <wait.h>


int main(void){
	struct sockaddr_in serv,*p;
	memset(&serv,0,sizeof(serv));
	p=&serv;
	p->sin_family=AF_INET;
	p->sin_addr.s_addr=htonl(INADDR_ANY);
	p->sin_port=htons(3000);
	
	int sk=socket(PF_INET,SOCK_STREAM,0);
	if(sk==-1){
		puts("socket error\n");
		exit(1);
	}
	
	int opt=1;
	setsockopt(sk,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); //服务器地址复用
	
	if(bind(sk,(struct sockaddr*)&serv,sizeof(serv))==-1){
		puts("bind error\n");
		exit(1);
	}
	
	if(listen(sk,10)==-1){
		puts("listen error\n");
		exit(1);
	}
	puts("listening port\n");
	int stat;
	
	while(1){
		int ck=accept(sk,NULL,NULL);     //父进程停留在这里,如连接到客户端,则产生一新子进程
	
		if(ck==-1){
			puts("accept error\n");
			continue;
		}else{
			puts("one client linking...");
		}
		
		pid_t pid=fork();     
		if(pid==0){                 //子进程开始
			
			int t=0;     
			while(t<10){
				write(ck,&t,sizeof(t));
				sleep(1);      
				t++;
			}
		    close(sk);
			close(ck);
			exit(0);   	//非常重要,子进程发出停止信号
    	}
		
		close(ck);      //非常重要,如没有这句,客户端不退出
		waitpid(-1,&stat,WNOHANG);       //父进程关闭停止的子进程
	}
	
	return 0;
}

1此程序accept在fork语句前,所以不会一次生成多个子进程,而是连接一个客户端后才生成一个新进程。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值