当前位置: 首页 > news >正文

湘潭网络公司网站建设建站宝盒免费下载

湘潭网络公司网站建设,建站宝盒免费下载,wordpress 多语言站点,网站开发总结 优帮云epollfork 实现高性能网络服务器 一般在服务器上,CPU是多核的,上述epoll实现方式只使用了其中的一个核,造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…

epoll+fork 实现高性能网络服务器
一般在服务器上,CPU是多核的,上述epoll实现方式只使用了其中的一个核,造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。

创建子进程函数–fork( )
要了解线程我们先来了解fork()函数:fork() 函数的功能是在当前的进程创建一个子进程;在多核时代,CPU管理多个进程,一个单核CPU同一时间只能运行一个进程,比如8 核的 CPU 只能同时运行 8 个进程。但是一个进程中可以有多个线程并行运行。

线程

为什么要有线程

在这里插入图片描述
首先线程不是一开始就被提出来的技术概念!!而是由历史的发展而来的,也就是说我们现在研究的是线程的动机是什么!

打个比喻就是一个引用程序要做很多工作!如web浏览器,又要显示图片,文字,视频的!
假如这三个动作是顺序执行的,也就是说,一个网页显示完图片再显示文字,再显示视频,那么很明显这对用户来说是体验非常不好的,这样对cpu的利用也不高!
那么此时,就引入了进程的概念!我们希望这些三个动作,也就是文字,图片,视频能够“同时”的显示在网页上,那么就是说这三个程序需要并发或者并行(能并行那是因为有多个cpu)执行,此时,我们的网页就可以”同时“显示这三个内容!因为并发的进程是走走停停,交替执行,这个速度很快,快到我们人认为是同时进行的!此时,我们把这些能够同时执行的任务成为”执行流“,也就是说,在进程的概念中,执行流就是进程!,这里又文字,图片,视频三个执行流!很明显我们知道进程的创建和切换,也就是说并发执行是很耗时耗费资源的!
所以我们又提出了线程的概念,也就是说我们能否在一个进程中,执行这三执行流,其实可以的!
线程就是在一个进程中的一个执行流!有线程的概念我们就可以在一个进程执行这三个任务,不需要创建多个进程,并且进行进程切换!我们的线程在一个进程中,可以并发或者并行的执行!这样就大大减少了资源开销!

从内存块的角度理解线程

在这里插入图片描述

  • 比如一个单线程的进程,其实他就等价于一个进程中的任务!和进程区别不大!这个线程(执行流)共享进程的代码段,数据段,打开文件的信息等内容!同时进程的栈空间也是线程的栈空间!
  • 假如有多线程的进程,比如三个线程:说明:这个进程中有三个执行流,这个三个会有三个不同的空间,但是都属于一个进程中,它们有自己的栈空间,能够单独的执行自己的任务!但是这三个线程共享一个进程中的代码段,数据段,打开文件的信息等。
  • 共享带来的好处就是访问这些共享资源的代价低,存储资源节省!不再需要进程那样又要多一份空间存储资源!

线程就是cpu调度的单位了,而进程就是资源分配的单位了,因为即使一个进程只有一个线程,真正执行的还是进程中的线程!

多线程模型

M:1模型
也就是多个用户线程对一个内核线程!
在这里插入图片描述
这种模型的好处就是,对于用户来说,它看的多个线程在并行执行!
在实际来说,多个线程占用一个内核线程,这个意思就是,用户线程中有一个线程占用了cpu资源,那么其他的用户线程就不可以执行,只能进入等待状态了!

1:1模型

一个用户线程对于一个内核线程,假如内核线程和用户线程数量不匹配的话,那么就会开多内核线程和用户线程匹配起来
在这里插入图片描述
好处就是多个线程真正意义上实现了并发或并行执行;
缺点就是:内核开销很大!

epoll+fork代码

这个代码就是每次fork一个进程,然后在每个线程里面可以用epoll申请多个进程来进行监听。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
//端口
#define PORT 8888
#define MESSAGE_LEN 1024
#define MAX_EVENTS 20
#define TIMEOUT 500
#define MAX_PROCESS 4int main(int argc,char* argv[]){int ret=-1;int on=1;int backlog=10;//缓冲区大小int socket_fd,accept_fd;struct sockaddr_in localaddr,remoteaddr;char in_buff[MESSAGE_LEN]={0,};int epoll_fd;struct epoll_event ev,events[MAX_EVENTS];//epoll中event的结构体int event_number;int flags = 1;pid_t pid=-1;socket_fd=socket(AF_INET,SOCK_STREAM,0);if(socket_fd==-1){std::cout<<"Failed to create socket!"<<std::endl;exit(-1);}//创建了socket之后我们要设置成异步的flags = fcntl(socket_fd,F_GETFL,0);//然后设置成非阻塞fcntl(socket_fd,F_SETFL,flags | O_NONBLOCK);ret=setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));if(ret==-1){std::cout<<"Failed to set socket options!"<<std::endl;}localaddr.sin_family=AF_INET;//地址族localaddr.sin_port=htons(PORT);//端口号localaddr.sin_addr.s_addr=INADDR_ANY;//这个就是0bzero(&(localaddr.sin_zero), 8);ret= bind(socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr));//绑定if(ret==-1){//绑定失败std::cout<<"Failed to bind addr!"<<std::endl;exit(-1);}ret = listen(socket_fd,backlog);//第二个是缓冲区大小,因为同一时间只能处理一个,其他都放在缓冲区if(ret==-1){std::cout<<"failed to listen socket!"<<std::endl;exit(-1);}for(int i=0;i<MAX_PROCESS;i++){//这个一般是cup数*2+1if(pid!=0){//pid==0代表着子进程,第一次等于-1,就是父进程,然后fork一个子进程pid=fork();//父进程,fork出来一个子进程}}if(pid==0){//创建epoll,再每个进程下面都可以创建epoll,每个进程自己使用自己的epollepoll_fd = epoll_create(256);//先将侦听的socket_fd添加进去,然后再将与数据通讯的客户端的socket_fd添加进去ev.events=EPOLLIN;//对于侦听的这个事件来说就是输入,就是in,这个一般不变成边缘触发,为了保证所有来的都能连上ev.data.fd=socket_fd;//这个就是文件描述符socketepoll_ctl(epoll_fd,EPOLL_CTL_ADD,socket_fd,&ev);while(1){//等待连接event_number = epoll_wait(epoll_fd,events,MAX_EVENTS,TIMEOUT);//发生事件的个数for(int i=0;i<event_number;i++){//有多少个文件描述符发生事件了if(events[i].data.fd==socket_fd){//如果这个是侦听的socket发生事件了,那么说明是来了新的连接std::cout<<"listen event..."<<std::endl;socklen_t addr_len=sizeof(struct sockaddr);accept_fd = accept(socket_fd,(struct sockaddr *)&remoteaddr,&addr_len);//设置成非阻塞//创建了socket之后我们要设置成异步的flags = fcntl(accept_fd,F_GETFL,0);//然后设置成非阻塞fcntl(accept_fd,F_SETFL,flags | O_NONBLOCK);ev.events=EPOLLIN | EPOLLET;//|上边缘触发ev.data.fd=accept_fd;epoll_ctl(epoll_fd,EPOLL_CTL_ADD,accept_fd,&ev);//将accept_fd添加到epoll中去}else if(events[i].events&EPOLLIN){//这里只介绍读的do{memset(in_buff, 0, sizeof(in_buff));//接收消息ret = recv(events[i].data.fd,(void *)in_buff,MESSAGE_LEN,0);if(ret==0){close(events[i].data.fd);}if(ret==MESSAGE_LEN){//缓冲区满了std::cout<<"maybe have data..."<<std::endl;}}while(ret<-1&&errno==EINTR);if(ret<0){switch(errno){case EAGAIN:break;dafault:break;}}if(ret>0){//打印信息std::cout<<"receive messaage:"<<in_buff<<std::endl;//返回消息send(events[i].data.fd,(void*)in_buff,MESSAGE_LEN,0);}}}}}else{//pid!=0,父进程do{//这时候父进程等待所有的子进程完成pid=waitpid(-1,NULL,0);}while(pid!=-1);}std::cout<<"quit servet...\n"<<std::endl;close(socket_fd);return 0;
}

异步事件的惊群现象

参考文献https://blog.csdn.net/m0_46606290/article/details/120939528

http://www.yayakq.cn/news/604701/

相关文章:

  • 文化馆网站建设意义提供设计的网站
  • logo网站推介wordpress更改数据库密码
  • 网站设计平台 动易网站备案查询 站长
  • 全国推广优化网站怎么编写一个网站
  • 网站兼容ie代码商标注册证查询网
  • 广州南沙网站建设网站建设罗贤伟
  • 陕西省住房和城乡建设网站企业服务公司排名
  • 站点搭建网站建设公司知名企业
  • 中国建设教育协会网站查询甘肃住房和城乡建设厅网站
  • 怎么建网站做江门企业自助建站系统
  • 开发网站合作协议北京网站建设是什么
  • 网站做图分辨率是多少合适那种转转假网站怎么做的
  • 查看网站开发网站域名备案服务
  • 网站美工设计公司电话怎么做能让网站尽快收录
  • 如何设计网站建设方案网站建设方案书 icp备案
  • 那个网站可以做软件出售的网站建设的功能需求分析
  • 服务器上 网站上海php网站建设
  • 攀枝花网站建设wordpress 模板 怎么用
  • 餐饮门户网站 方案怎么做百度投诉电话人工服务总部
  • 市建设局网站施工企业跨专业接工作是否有效
  • wordpress 直播网站吗网站开发教学视频
  • php做网站示例网站开发工作前景
  • 汕头网站优化电话青浦建设网站公司
  • 互动网站设计wordpress安装在本地安装
  • 求个网站2020急急急胶州建网站
  • 云南建网站做消费金融网站价格
  • 滁州网站建设工作室h5链接是什么意思
  • 湛江网站设计哪家好二手域名
  • 快速网站如何做国外的电商网站
  • 百度头条怎么做网站公众号开发教程零基础