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

新闻网站诚信建设工作总结怎样打小广告最有效

新闻网站诚信建设工作总结,怎样打小广告最有效,如何在虚拟主机一键安装wordpress,英国做电商网站有哪些记录下 一个线程专门用来接受accept获取客户端的fd 获取fd之后 从剩余的执行线程中 找到一个连接客户端数量最少的线程 然后将客户端的fd加入到这个线程中并通过EPOLL监听这个fd 线程之间通过eventfd来通信 将客户端的fd传到 对应的线程中 参考了MediaServer 引入…

记录下  

一个线程专门用来接受accept获取客户端的fd 

获取fd之后 从剩余的执行线程中 找到一个连接客户端数量最少的线程

然后将客户端的fd加入到这个线程中并通过EPOLL监听这个fd

线程之间通过eventfd来通信  将客户端的fd传到 对应的线程中  

参考了MediaServer   引入EventPollerPoll 和 EventPoller的 概念  

最少两个两个线程 设置为1的话 会改成2

cpp代码:

#include "durian.h"#include <sys/epoll.h>namespace DURIAN
{EventPoller::EventPoller(int id){m_id = id;}EventPoller::~EventPoller(){printf("~EventPoller signal m_id = %d m_run_flag = %d\n",m_id,m_run_flag);Wait();}bool EventPoller::Init(){m_poll_fd = epoll_create1(0);if(m_poll_fd == -1){return false;}m_event_fd = eventfd(0,0);if(m_event_fd == -1){printf("new fd failed\n");close(m_poll_fd);return false ;}return true;}void EventPoller::RunLoop(){static const int MAX_EVENTS = 1024;struct epoll_event events[MAX_EVENTS];while(m_run_flag){int ready_count = epoll_wait(m_poll_fd,events,MAX_EVENTS,2000);if(ready_count == -1){if(errno != EINTR){//exit(1);}//ready_count = 0;}else if(ready_count == 0){if(m_run_flag == false){//printf("time out and runflag = false exit thread\n");//break;}}for(int i = 0;i<ready_count;i++){const struct epoll_event &ev = events[i];int fd = events[i].data.fd;if(ev.events &(EPOLLIN | EPOLLERR |EPOLLHUP)){auto handler = m_accept_handlers[fd];handler(fd);}else if(ev.events & (EPOLLOUT | EPOLLERR | EPOLLHUP)){auto it = m_buffer_pool.find(fd);if(it!= m_buffer_pool.end()){auto &buf = it->second;if(buf.WriteData(fd) == false){Close(fd);}}}}}}int EventPoller::GetEventFD(){return m_event_fd;}int EventPoller::GetClients(){return m_accept_handlers.size();}void EventPoller::Stop(){m_run_flag = false;}void EventPoller::Start(){//printf("Enter EventPoller Start  m_id = %d pollfd = %d eventid = %d\n",m_id,m_poll_fd,m_event_fd);m_run_flag = true;m_thread_id = std::thread(&EventPoller::RunLoop,this);}void EventPoller::Wait(){if(m_thread_id.joinable()){m_thread_id.join();}}bool EventPoller::Add2Epoll(int fd){if(m_accept_handlers.count(fd) != 0){return false;}int flags = 1;if(ioctl(fd,FIONBIO,&flags) == -1){return false;}struct epoll_event ev;ev.events = EPOLLIN |EPOLLOUT |EPOLLET;ev.data.fd = fd;if(epoll_ctl(m_poll_fd,EPOLL_CTL_ADD,fd,&ev)==-1){return false;}return true;}void EventPoller::DeliverConn(int conn_fd){//printf("DeliverConn fd = %d\n",conn_fd);uint64_t count = conn_fd;if(write(m_event_fd,&count,sizeof(count)) == -1){printf("Deliverconn write failed\n");}}bool EventPoller::AddListener(int fd,ACCEPTER on_accept){if(Add2Epoll(fd) == false){return false;}std::cout<<"EventPoller AddListener fd = "<<fd<<std::endl;m_accept_handlers[fd] = [this,on_accept]( int server_fd){for(;;){int new_fd = accept(server_fd,nullptr,nullptr);std::cout<<"accept client fd = "<<new_fd<<std::endl;	if(new_fd == -1){if(errno!= EAGAIN){Close(server_fd);}return 0;}int enable = 1;setsockopt(new_fd,IPPROTO_TCP,TCP_NODELAY,&enable,sizeof(enable));on_accept(new_fd);}return 0;};return true;}bool EventPoller::AddEventer(int fd, EVENTER on_event){if(Add2Epoll(fd) == false){return false;}m_accept_handlers[fd] = [this,on_event](int cfd){for(;;){uint64_t count;if(read(cfd,&count,sizeof(count)) == -1){if(errno != EAGAIN){Close(cfd);}return 0;}on_event(count);}return 0;};return true;}bool EventPoller::AddReader(int fd, READER on_read){	if(Add2Epoll(fd) == false){return false;}m_accept_handlers[fd] = [this,on_read](int cfd){for(;;){char buf[4096] = {0};ssize_t ret = read(cfd,buf,sizeof(buf));if(ret == -1){if(errno != EAGAIN){Close(cfd);}return -1;}if(ret == 0){Close(cfd);printf("客户端关闭了连接 %d\n",cfd);return 0 ;}on_read(cfd,buf,ret);}};return true;}void EventPoller::Close(int fd){m_accept_handlers.erase(fd);m_buffer_pool.erase(fd);close(fd);}bool EventPoller::FlushData(int fd, const char * buf, size_t len){WriteBuffer *wb = nullptr;auto it = m_buffer_pool.find(fd);if(it == m_buffer_pool.end()){while(len >0){ssize_t ret = write(fd,buf,len);if(ret == -1){if(errno != EAGAIN){Close(fd);return false;}wb = &m_buffer_pool[fd];break;}buf+= ret;len-=ret;}if(len == 0){//Successreturn true;}}else{wb = &it->second;}wb->Add2Buffer(buf,len);return true;}static size_t g_pool_size = 0;
void EventPollerPool::SetPoolSize(size_t size)
{g_pool_size = size;
}
EventPollerPool & EventPollerPool::Instance()
{static std::shared_ptr<EventPollerPool> s_instance(new EventPollerPool()); static EventPollerPool &s_instance_ref = *s_instance; return s_instance_ref; 
}EventPollerPool::EventPollerPool()
{auto size = g_pool_size;auto cpus = std::thread::hardware_concurrency();size = size > 0 ? size : cpus;std::cout<<"Thread size:"<<size<<std::endl;if(size <2)size = 2;for (int i = 0; i < size; ++i) {std::shared_ptr<EventPoller> poller = std::make_shared<EventPoller>(i);m_pollers.emplace_back(poller);}
}std::shared_ptr<EventPoller> EventPollerPool::GetPoller()
{if(m_pollers.size()>1){int min_clients = 10000;int target_index = 0;for(int i = 1;i<m_pollers.size();i++){if(m_pollers[i]-> GetClients() < min_clients){min_clients = m_pollers[i]->GetClients();target_index = i;}}//printf("target index = %d min_clients = %d\n",target_index,min_clients);return m_pollers[target_index];}return m_pollers[0];}
std::shared_ptr<EventPoller> EventPollerPool::GetFirstPoller()
{return m_pollers[0];
}void EventPollerPool::StartPollers()
{for(int i = 1;i<m_pollers.size();i++){m_pollers[i]->Init();int event_fd = m_pollers[i]->GetEventFD();m_pollers[i]->AddEventer(event_fd,[&,i](uint64_t cfd){READER reader = [&,i](int fd,const char*data,size_t len){printf("Len[%s] content[%d] m_pollers[i] = %p i = %d\n",data,len,m_pollers[i],i);m_pollers[i]->FlushData(fd,data,len);return 0;};m_pollers[i]->AddReader(cfd,reader);return 0;});m_pollers[i]->Start();	}
}void EventPollerPool::Stop()
{for(int i = 0;i<m_pollers.size();i++){m_pollers[i]->Stop();}}}

头文件

#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netinet/tcp.h>#include <sys/eventfd.h>
#include <signal.h>#include <iostream>
#include <memory>
#include <list>
#include <vector>
#include <functional>
#include <thread>
#include <mutex>#include <unordered_map>namespace DURIAN
{class WriteBuffer{private:std::list<std::string> buf_items;size_t offset = 0;public:bool IsEmpty() const{return buf_items.empty();}void Add2Buffer(const char* data,size_t len){if(buf_items.empty() || buf_items.back().size()+len >4096){buf_items.emplace_back(data,len);}else{buf_items.back().append(data,len);}}bool WriteData(int fd){while (IsEmpty() == false){auto const &item = buf_items.front();const char *p = item.data() + offset;size_t len = item.size() -offset;while(len >0){ssize_t ret = write(fd,p,len);if(ret == -1){if(errno == EAGAIN){return true;}return false;}offset += ret;p+=ret;len-= ret;}buf_items.pop_front();}return true;}};using ACCEPTER = std::function<int(int)>;using WRITER = std::function<int(int)>;using EVENTER = std::function<int(int)>;using READER = std::function<int(int,const char *data,size_t)>;//static thread_local std::unordered_map<int fd,READER>g_th_handlers;class EventPoller{private:int m_poll_fd = -1;int m_id;bool m_run_flag = false;std::unordered_map<int,ACCEPTER> m_accept_handlers;std::unordered_map<int,WriteBuffer> m_buffer_pool;std::mutex m_connction_lock;int m_event_fd;std::thread m_thread_id ;std::vector<int>m_connections;void RunLoop();public:EventPoller(int i);~EventPoller();int GetEventFD();int GetClients();std::vector<int> & GetConnections();bool Init();void Start();void Stop();void Wait();	void DeliverConn(int conn_fd);bool AddListener(int fd,ACCEPTER on_listen);bool AddEventer(int fd,EVENTER on_event);bool AddReader(int fd,READER on_read);void Close(int fd);bool Add2Epoll(int fd);bool FlushData(int fd,const char *buf,size_t len);};class EventPollerPool{public:static EventPollerPool &Instance();static void SetPoolSize(size_t size = 0);std::shared_ptr<EventPoller>GetPoller(); std::shared_ptr<EventPoller>GetFirstPoller(); 	void StartPollers();void Stop(); private:int m_size;std::vector<std::shared_ptr<EventPoller>> m_pollers;EventPollerPool();		  };}

main文件

#include "durian.h"static bool g_run_flag = true;
void sig_handler(int signo)
{signal(SIGINT, SIG_IGN);signal(SIGTERM, SIG_IGN);signal(SIGKILL, SIG_IGN);g_run_flag = false;printf("Get exit flag\n");if (SIGINT == signo || SIGTSTP == signo || SIGTERM == signo|| SIGKILL == signo){g_run_flag = false;printf("\033[0;31mprogram exit by kill cmd !\033[0;39m\n");}}bool StartServer()
{int listen_fd = socket(AF_INET,SOCK_STREAM,0);if(listen_fd == -1){printf("Create socket failed\n");return false;}else{printf("Server listen fd is:%d\n",listen_fd);}int reuseaddr = 1;if(setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr ,sizeof(reuseaddr)) == -1){return false;}struct sockaddr_in listen_addr = {0};listen_addr.sin_family  = AF_INET;listen_addr.sin_addr.s_addr = INADDR_ANY;listen_addr.sin_port = htons(8888);if(bind(listen_fd,(struct sockaddr*)&listen_addr,sizeof(listen_addr)) == -1){printf("bind failed\n");return false;}if(listen(listen_fd,100) == -1){printf("listen failed\n");return false;}DURIAN::EventPollerPool::SetPoolSize(1);DURIAN::EventPollerPool& pool = DURIAN::EventPollerPool::Instance(); pool.StartPollers();auto poller = pool.GetFirstPoller(); if(poller->Init()){if(poller->AddListener(listen_fd,[&](int conn_fd){printf("将新的fd加到epoll监听 fd =%d\n",conn_fd);//Deliver client fd to other pollerspool.GetPoller()->DeliverConn(conn_fd);return 0;}) == false){return false;}poller->Start();}while(g_run_flag){sleep(2);}pool.Stop();}void StopServer()
{DURIAN::EventPollerPool& pool = DURIAN::EventPollerPool::Instance(); pool.Stop();
}int main(int argc,char *argv[])
{printf(" cpp version :%d\n",__cplusplus);int thread_size = 1;bool run_flag = true;signal(SIGPIPE,SIG_IGN);signal(SIGTERM, sig_handler);signal(SIGKILL, sig_handler);signal(SIGINT,sig_handler); StartServer();return 0;
}

性能测试

ulimit -HSn 102400

ab -n 100000 -c 20000 http://192.168.131.131:8888/index.html
 


文章转载自:
http://dinncosonograph.stkw.cn
http://dinncogymnosophist.stkw.cn
http://dinncospae.stkw.cn
http://dinncobarkhausen.stkw.cn
http://dinncomithridate.stkw.cn
http://dinncocollocable.stkw.cn
http://dinncopay.stkw.cn
http://dinncoautoff.stkw.cn
http://dinncoddn.stkw.cn
http://dinncobackhanded.stkw.cn
http://dinncoreefy.stkw.cn
http://dinncosuperorganic.stkw.cn
http://dinncothresh.stkw.cn
http://dinncosonnet.stkw.cn
http://dinncoidentity.stkw.cn
http://dinncohatch.stkw.cn
http://dinncophotodetector.stkw.cn
http://dinncorubral.stkw.cn
http://dinncocovenantee.stkw.cn
http://dinncocastalie.stkw.cn
http://dinncoaleut.stkw.cn
http://dinncoipm.stkw.cn
http://dinncohomemade.stkw.cn
http://dinncooneiromancy.stkw.cn
http://dinncoovernumber.stkw.cn
http://dinncoergotrate.stkw.cn
http://dinncoplayclothes.stkw.cn
http://dinncopolyglottous.stkw.cn
http://dinncoreflectible.stkw.cn
http://dinncoscofflaw.stkw.cn
http://dinncoamende.stkw.cn
http://dinncostenographer.stkw.cn
http://dinncoporn.stkw.cn
http://dinncopoc.stkw.cn
http://dinncobluegrass.stkw.cn
http://dinncounderclothes.stkw.cn
http://dinncomarsala.stkw.cn
http://dinncofishway.stkw.cn
http://dinncocrucis.stkw.cn
http://dinncorawinsonde.stkw.cn
http://dinncocyclohexane.stkw.cn
http://dinncofibroblast.stkw.cn
http://dinncointravital.stkw.cn
http://dinncounderslung.stkw.cn
http://dinncounpile.stkw.cn
http://dinncofilaria.stkw.cn
http://dinncocondense.stkw.cn
http://dinncopediculate.stkw.cn
http://dinncotreasury.stkw.cn
http://dinncohurds.stkw.cn
http://dinncomacaroni.stkw.cn
http://dinncopurposely.stkw.cn
http://dinncoparrot.stkw.cn
http://dinncoseism.stkw.cn
http://dinncodoric.stkw.cn
http://dinncoupload.stkw.cn
http://dinncoliven.stkw.cn
http://dinncoscratchy.stkw.cn
http://dinncosexennium.stkw.cn
http://dinncofreeload.stkw.cn
http://dinncopackthread.stkw.cn
http://dinncobattlements.stkw.cn
http://dinncopneumoangiography.stkw.cn
http://dinncobacteremia.stkw.cn
http://dinncoreprehensibly.stkw.cn
http://dinncobalanced.stkw.cn
http://dinncofloat.stkw.cn
http://dinncochronogram.stkw.cn
http://dinncoethnos.stkw.cn
http://dinncocycad.stkw.cn
http://dinncoeidolon.stkw.cn
http://dinncoskateboard.stkw.cn
http://dinncophilibeg.stkw.cn
http://dinncoimpetus.stkw.cn
http://dinncogalvanoplastics.stkw.cn
http://dinncoboarfish.stkw.cn
http://dinncoexpressionism.stkw.cn
http://dinncocurite.stkw.cn
http://dinncolife.stkw.cn
http://dinncounveracity.stkw.cn
http://dinncovodkatini.stkw.cn
http://dinncomariolatry.stkw.cn
http://dinncoorthoclase.stkw.cn
http://dinncopatronym.stkw.cn
http://dinncounisonant.stkw.cn
http://dinncoqueasiness.stkw.cn
http://dinncosamian.stkw.cn
http://dinncofossa.stkw.cn
http://dinncosenor.stkw.cn
http://dinncospermatozoid.stkw.cn
http://dinncomarsala.stkw.cn
http://dinncoantiphrasis.stkw.cn
http://dinncofighting.stkw.cn
http://dinncodiabetes.stkw.cn
http://dinncopirogi.stkw.cn
http://dinncobowerbird.stkw.cn
http://dinncorhinoscope.stkw.cn
http://dinncoinsectual.stkw.cn
http://dinncobridoon.stkw.cn
http://dinncoorangeade.stkw.cn
http://www.dinnco.com/news/130275.html

相关文章:

  • 快速做网站费用域名检测查询
  • 贵州建设工程招投标协会网站优化怎么做
  • 沈阳网站建设的公司云南网络营销公司
  • 商贸公司寮步网站建设价钱郑州计算机培训机构哪个最好
  • 在linux上做网站搭建代写文章多少钱
  • 国外房屋设计网站seo去哪学
  • 山西制作网站公司排名windows优化大师是什么软件
  • 个人可以做宣传片视频网站如何开网店
  • 铭万做网站怎么样时事新闻热点
  • 企业网站的建设原则是什么?怎么做好seo内容优化
  • 惠州市网站建设个人网络推广费用一般多少
  • 一了网站个人发布信息免费推广平台
  • 南京江北新区seo哪个软件好
  • 网站建设 会计处理短链接
  • 英文 edm营销 的网站 与 工具个人怎么做免费百度推广
  • 西安代做毕业设计网站苏州网站建设公司
  • 中国招投标采购网官网seo官网优化怎么做
  • 网站设计的公司蒙特青岛网站优化公司
  • 建设工程竞标网站贵州seo技术查询
  • 常德做网站的公司岳阳网站界面设计
  • 做的精美的门户网站推荐做灰色词seo靠谱
  • 山东青岛网站建设关键词排名优化官网
  • 要建网站怎么做网络推广seo教程
  • 衡水微信网站建设江苏企业seo推广
  • wordpress网站好慢谷歌推广公司
  • 餐饮行业做网站的数据seo建站系统
  • 芜湖网站建设百度推广开户渠道
  • 山西网站建设报价单百度推广账户登录
  • 东莞网站建设公司网站关键词怎么写
  • 做视频能赚钱的网站中央下令全国各地核酸检测