Linux网络编程:多进程和多线程并发服务器

1、多进程并发服务器分析

**并发**:将CPU分割成不同的时间碎片,不同的进程就是去抢时间碎片,而且进程对于抢时间碎片是有优先级的,也就是有的进程抢到时间碎片的概率更大。
通俗点并发就是在一短时间之内,所能处理的进程的个数,高并发就是处理的进程个数多。

(1)只能处理单链接
1. 创建套接字-这个套接字用于监听(也就是用于监听的文件描述符(一个缓存区)和用于通信的文件描述符是不同的)
2. 绑定
3. 监听–listen(fd,128);
4. -----------------------------
5. 接受连接请求-会生成一个用于通信的文件描述符(一个用于通信的缓存区)
6. 通信
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
子进程就是用来进行通信的。
在这里插入图片描述

//伪代码:
void recyle(int num)
{
	while(waitpid(-1,NULL,WNOHANG)>0);
}
int main()
{
	//	创建监听的套接字文件描述符
	int lfd = socket();
	//绑定
	bind();
	//设置监听
	listen();
	//父进程
	while(1)
	{
		int cfd = accept();//父进程会在这里阻塞,直到有客服端建立连接,通过返回的cfd今次那个判断
		//当建立链接之后,创建一个子进程用于通信,因为进程间共享文件描述符,所以父进程建立的通信的描述符子进程也可以用
		pid_t = pid;
		if(pid==0)
		{
			close(lfd);//将用于监听的套接字文件描述符关闭,用cfd即可
			//通信
			while(1)
			{
				int len = read();//read相当于接受数据,也就是在读的缓存区接收数据
				if(len == -1)
					exit;
				else if(len == 0)
				{
					close(cfd);
					break;
				}
				write();
			}
			//退出子进程
			return 0;//或者exit(0)
		}
		else{//父进程进行资源回收
			close(cfd);//父进程不用于通信,所以关闭,此时子进程的cfd不会关闭,因为进程写时复制
			//不能用while回收子进程,因为这样会父进程不会往下进程,也就是只能接受一个子进程通信,所以用信号进行回收
				struct sigaction act;
				act.sa_handler = recyle;
				act.sa_falgs = 0;
				sigemptyset($act.sa_mask);
				sigaction(SIGCHLD,&act,NULL);
				
		}	

小结:父进程用于监听,子进程用于通信,代码中看似只有一个cfd,但实际每一个子进程都有自己独立的cfd,因为会复制一份,所以进程之间的cfd是不会相互影响的。

2、多进程并发服务器分析

多线程并发服务器与进程的相似,不同的地方是创建线程的代码,以及线程之间的共享资源,地址空间这些细节会使得实现有一些细节的不同。
进程中只要声明一个cfd就能搞定,因为进程有读时共享,写时复制,而线程并不能一个cfd搞定,因为所有的线程会共享全局变量,所以线程之间是相同的cfd地址,会造成混乱。所以需要用数组去保存每一个线程的用于通信的文件描述符。

在这里插入图片描述
线程:①共享全局静态存储区和堆内存;②栈是独立的

//伪代码:
typedef struct sockInfo
{
	pthread_t id;
	int fd;
	struct sockaddr addr;
} SockInfo;
void* worker(void *arg)
{
	while(1)
	{
		//打印客户端ip和port
		read();
		write();
	}	
}
int main()
{
	//	创建监听的套接字文件描述符
	int lfd = socket();
	int* fds = new int[100];//最多100个线程
	//绑定
	bind();
	//设置监听
	listen();
	SockInfo sock[256];
	//父线程
	while(1)
	{
		sock[i].fd = accept(lfd,&client,&len);
		//创建子线程
		//子线程进行通信
		pthread_create(&sock[i].id,NULL,worker,&sock[i]);
		//分离父子线程
		pthread_deathch(sock[i].id);
	}
}

小结:不能用一块内存存取多个进程的文件描述符,线程中执行的是一个回调函数内容,因为线程中的数据需要是独立的,所以我们定义一个结构体,将每一个线程需要的东西全封装在结构体中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值