日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高并发的epoll+线程池,epoll在线程池内

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高并发的epoll+线程池,epoll在线程池内 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
epoll是linux下高并發服務器的完美方案,因為是基于事件觸發的,所以比select快的不只是一個數量級。 單線程epoll,觸發量可達到15000,但是加上業務后,因為大多數業務都與數據庫打交道,所以就會存在阻塞的情況,這個時候就必須用多線程來提速。 epoll在線程池內,測試結果2000個/s 增加了網絡斷線后的無效socket檢測。 測試工具:stressmark 因為加了適用與ab的代碼,所以也可以適用ab進行壓力測試。 char buf[1000] = {0};
sprintf(buf,"HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s","Hello world!\n");
send(socketfd,buf, strlen(buf),0); #include<stdio.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>


//stl head

#include <ext/hash_map>//包含hash_map 的頭文件

//#include
//stl的map

using namespace std ; //std 命名空間

using namespace __gnu_cxx ; //而hash_map是在__gnu_cxx的命名空間里的



int init_thread_pool ( int threadNum ) ;
void *epoll_loop ( void * para ) ;
void *check_connect_timeout ( void * para ) ;


struct sockStruct
{
???? time_t time ;

???? unsigned int * recvBuf ;
} ;

//hash-map

//hash_map????????sock_map;

hash_map < int , sockStruct >????????sock_map ;

?
# define MAXRECVBUF 4096
# define MAXBUF MAXRECVBUF +10

int fd_Setnonblocking ( int fd )
{
???? int op ;
?
????op =fcntl (fd ,F_GETFL ,0 ) ;
????fcntl (fd ,F_SETFL ,op |O_NONBLOCK ) ;
?
???? return op ;
}
?
void on_sigint ( int signal )
{
???? exit (0 ) ;
}
?
/*
handle_message - 處理每個 socket 上的消息收發
*/

int handle_message ( int new_fd )
{
???? char buf [MAXBUF + 1 ] ;
???? char sendbuf [MAXBUF +1 ] ;
???? int len ;
???? /* 開始處理每個新連接上的數據收發 */
????bzero (buf , MAXBUF + 1 ) ;
???? /* 接收客戶端的消息 */
???? //len = recv(new_fd, buf, MAXBUF, 0);



???? int nRecvBuf = MAXRECVBUF ; //設置為32K

???? setsockopt (new_fd , SOL_SOCKET , SO_RCVBUF , ( const char * ) &nRecvBuf , sizeof ( int ) ) ;
????len = recv (new_fd , &buf , MAXBUF ,0 ) ;

???? //--------------------------------------------------------------------------------------------

???? //這塊為了使用ab測試

???? char bufSend [1000 ] = {0 } ;
???? sprintf (bufSend , "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s" , "Hello world!\n" ) ;
???? send (new_fd ,bufSend , strlen (buf ) ,0 ) ;

???? //--------------------------------------------------------------------------------------------


???? if (len > 0 ) {

???????? //printf ("%d接收消息成功:'%s',共%d個字節的數據\n", new_fd, buf, len);


???????? //hash-map

????????
????????hash_map < int , sockStruct > : : iterator it_find ;
????????it_find = sock_map . find (new_fd ) ;
???????? if (it_find = = sock_map .end ( ) ) {
???????????? //新的網絡連接,申請新的接收緩沖區,并放入map中

???????????? //printf("new socket %d\n", new_fd);


????????????sockStruct newSockStruct ;
????????????newSockStruct . time = time ( ( time_t * )0 ) ;
????????????newSockStruct .recvBuf = ( unsigned int * ) malloc (1000 ) ;
???????????? memset (newSockStruct .recvBuf , 0 , 1000 ) ;
???????????? strcat ( ( char * )newSockStruct .recvBuf , buf ) ;
????????????sock_map .insert ( pair < int ,sockStruct > (new_fd , newSockStruct ) ) ;
???????? } else {
???????????? //網絡連接已經存在,找到對應的數據緩沖區,將接收到的數據拼接到數據緩沖區中

???????????? //printf("socket %d exist!\n", it_find->first);


???????????? (it_find - >second ) . time = time ( ( time_t * )0 ) ;???????????????? //時間更改

???????????? char * bufSockMap = ( char * ) (it_find - >second ) .recvBuf ;???? //數據存儲


???????????? strcat (bufSockMap , buf ) ;
???????????? //printf("bufSockMap:%s\n", bufSockMap);

???????? }


???? }
???? else {
???????? if (len < 0 )
???????????? printf ( "消息接收失敗!錯誤代碼是%d,錯誤信息是'%s'\n" ,
???????????? errno , strerror ( errno ) ) ;
???????? else {
???????????? //將socket從map中移除

???????????? /*
????????????hash_map::iterator it_find;
????????????it_find = sock_map.find(new_fd);
????????????sock_map.erase(it_find);
????????????*/

???????????? printf ( "client %d quit!\n" ,new_fd ) ;
???????? }
???????? //close(new_fd);

???????? return -1 ;
???? }
???? /* 處理每個新連接上的數據收發結束 */

???? //關閉socket的時候,要釋放接收緩沖區。

????hash_map < int , sockStruct > : : iterator it_find ;
????it_find = sock_map . find (new_fd ) ;
???? free ( (it_find - >second ) .recvBuf ) ;
????sock_map .erase (it_find ) ;

???? close (new_fd ) ;
???? return len ;
}


???? int listenfd ;
???? int sock_op =1 ;
???? struct sockaddr_in address ;
???? struct epoll_event event ;
???? struct epoll_event events [1024 ] ;
???? int epfd ;
???? int n ;
???? int i ;
???? char buf [512 ] ;
???? int off ;
???? int result ;
???? char *p ;

int main ( int argc , char * argv [ ] )
{

????init_thread_pool (1 ) ;

???? signal (SIGPIPE , SIG_IGN ) ;
???? signal (SIGCHLD , SIG_IGN ) ;
???? signal ( SIGINT , &on_sigint ) ;
????listenfd = socket ( AF_INET , SOCK_STREAM ,0 ) ;
???? setsockopt (listenfd ,SOL_SOCKET ,SO_REUSEADDR , &sock_op , sizeof (sock_op ) ) ;
?
???? memset ( &address ,0 , sizeof (address ) ) ;
????address .sin_addr .s_addr = htonl ( INADDR_ANY ) ;
????address .sin_port = htons (8006 ) ;
???? bind (listenfd , ( struct sockaddr * ) &address , sizeof (address ) ) ;
???? listen (listenfd ,1024 ) ;
????fd_Setnonblocking (listenfd ) ;
?
????epfd =epoll_create (65535 ) ;
???? memset ( &event ,0 , sizeof (event ) ) ;
????event .data .fd =listenfd ;
????event .events =EPOLLIN |EPOLLET ;
????epoll_ctl (epfd ,EPOLL_CTL_ADD ,listenfd , &event ) ;

???? while (1 ) {
???????? sleep (1000 ) ;
???? }
???? return 0 ;
}

/*************************************************
* Function: * init_thread_pool
* Description: * 初始化線程
* Input: * threadNum:用于處理epoll的線程數
* Output: *
* Others: * 此函數為靜態static函數,
*************************************************/

int init_thread_pool ( int threadNum )
{
???? int i ,ret ;

???? pthread_t threadId ;

???? //初始化epoll線程池

???? for ( i = 0 ; i < threadNum ; i + + )
???? {

????????ret = pthread_create ( &threadId , 0 , epoll_loop , ( void * )0 ) ;
???????? if (ret ! = 0 )
???????? {
???????????? printf ( "pthread create failed!\n" ) ;
???????????? return ( -1 ) ;
???????? }
???? }

????ret = pthread_create ( &threadId , 0 , check_connect_timeout , ( void * )0 ) ;

???? return (0 ) ;
}
/*************************************************
* Function: * epoll_loop
* Description: * epoll檢測循環
* Input: *
* Output: *
* Others: *
*************************************************/

static int count111 = 0 ;
static time_t oldtime = 0 , nowtime = 0 ;
void *epoll_loop ( void * para )
{
???????? while (1 )
???? {
????????n =epoll_wait (epfd ,events ,4096 , -1 ) ;
???????? //printf("n = %d\n", n);

???????? if (n >0 )
???????? {
???????????? for (i =0 ;i <n ; + +i )
???????????? {
???????????????? if (events [i ] .data .fd = =listenfd )
???????????????? {
???????????????????? while (1 )
???????????????????? {
????????????????????????event .data .fd = accept (listenfd , NULL , NULL ) ;
???????????????????????? if (event .data .fd >0 )
???????????????????????? {
????????????????????????????fd_Setnonblocking (event .data .fd ) ;
????????????????????????????event .events =EPOLLIN |EPOLLET ;
????????????????????????????epoll_ctl (epfd ,EPOLL_CTL_ADD ,event .data .fd , &event ) ;
???????????????????????? }
???????????????????????? else
???????????????????????? {
???????????????????????????? if ( errno = =EAGAIN )
???????????????????????????? break ;
???????????????????????? }
???????????????????? }
???????????????? }
???????????????? else
???????????????? {
???????????????????? if (events [i ] .events &EPOLLIN )
???????????????????? {
???????????????????????? //handle_message(events[i].data.fd);


???????????????????????? char recvBuf [1024 ] = {0 } ;

???????????????????????? int ret = 999 ;

???????????????????????? int rs = 1 ;


???????????????????????? while (rs )
???????????????????????? {
????????????????????????????ret = recv (events [n ] .data .fd ,recvBuf ,1024 ,0 ) ; // 接受客戶端消息

???????????????????????????? if (ret < 0 )
???????????????????????????? {
???????????????????????????????? //由于是非阻塞的模式,所以當errno為EAGAIN時,表示當前緩沖區已無數據可//讀在這里就當作是該次事件已處理過。

???????????????????????????????? if ( errno = = EAGAIN )
???????????????????????????????? {
???????????????????????????????????? printf ( "EAGAIN\n" ) ;
???????????????????????????????????? break ;
???????????????????????????????? }
???????????????????????????????? else {
???????????????????????????????????? printf ( "recv error!\n" ) ;
????????????????????????????????????epoll_ctl (epfd , EPOLL_CTL_DEL , events [i ] .data .fd , &event ) ;
???????????????????????????????????? close (events [i ] .data .fd ) ;
???????????????????????????????????? break ;
???????????????????????????????? }
???????????????????????????? }
???????????????????????????? else if (ret = = 0 )
???????????????????????????? {
???????????????????????????????? // 這里表示對端的socket已正常關閉.

????????????????????????????????rs = 0 ;
???????????????????????????? }
???????????????????????????? if (ret = = sizeof (recvBuf ) )
????????????????????????????????rs = 1 ; // 需要再次讀取

???????????????????????????? else
????????????????????????????????rs = 0 ;
???????????????????????? }




???????????????????????? if (ret >0 ) {

????????????????????????????count111 + + ;



???????????????????????????? struct tm *today ;
???????????????????????????? time_t ltime ;
???????????????????????????? time ( &nowtime ) ;

???????????????????????????? if (nowtime ! = oldtime ) {
???????????????????????????????? printf ( "%d\n" , count111 ) ;
????????????????????????????????oldtime = nowtime ;
????????????????????????????????count111 = 0 ;
???????????????????????????? }


???????????????????????????? char buf [1000 ] = {0 } ;
???????????????????????????? sprintf (buf , "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s" , "Hello world!\n" ) ;
???????????????????????????? send (events [i ] .data .fd ,buf , strlen (buf ) ,0 ) ;


???????????????????????????? //????CGelsServer Gelsserver;

???????????????????????????? //????Gelsserver.handle_message(events[i].data.fd);

???????????????????????? }


????????????????????????epoll_ctl (epfd , EPOLL_CTL_DEL , events [i ] .data .fd , &event ) ;
???????????????????????? close (events [i ] .data .fd ) ;

???????????????????? }
???????????????????? else if (events [i ] .events &EPOLLOUT )
???????????????????? {
???????????????????????? sprintf (buf , "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s" , "Hello world!\n" ) ;
???????????????????????? send (events [i ] .data .fd ,buf , strlen (buf ) ,0 ) ;
???????????????????????? /*
????????????????????????if(p!=NULL)
????????????????????????{
????????????????????????????free(p);
????????????????????????????p=NULL;
????????????????????????}
????????????????????????*/

???????????????????????? close (events [i ] .data .fd ) ;
???????????????????? }
???????????????????? else
???????????????????? {
???????????????????????? close (events [i ] .data .fd ) ;
???????????????????? }
???????????????? }
???????????? }
???????? }
???? }

}
/*************************************************
* Function: * check_connect_timeout
* Description: * 檢測長時間沒反應的網絡連接,并關閉刪除
* Input: *
* Output: *
* Others: *
*************************************************/

void *check_connect_timeout ( void * para )
{
????hash_map < int , sockStruct > : : iterator it_find ;
???? for (it_find = sock_map .begin ( ) ; it_find!=sock_map .end ( ) ; + +it_find ) {
???????? if ( time ( ( time_t * )0 ) - (it_find - >second ) . time > 120 ) {???????????????? //時間更改


???????????? free ( (it_find - >second ) .recvBuf ) ;
????????????sock_map .erase (it_find ) ;

???????????? close (it_find - >first ) ;
???????? }
???? }

}

總結

以上是生活随笔為你收集整理的高并发的epoll+线程池,epoll在线程池内的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美亚洲日本一区 | 韩国三级hd中文字幕叫床浴室 | 国产一级啪啪 | 精品国产aⅴ一区二区三区四川人 | 亚洲欧美伦理 | 亚洲国产私拍精品国模在线观看 | 日本老妇高潮乱hd | 黄色三级在线观看 | 波多野结衣av电影 | 国产美女视频免费观看下载软件 | 小嫩嫩12欧美 | 欧美aⅴ在线观看 | 日本在线视频免费 | 日日爽日日操 | 国产欧美一区二区三区鸳鸯浴 | 天天操天天操天天操天天操 | 国产香蕉久久 | 精品国产一区二区三区久久久蜜月 | 亚洲精品a级 | 91精品在线免费观看 | 99精品欧美一区二区蜜桃免费 | 黄色小视频在线观看免费 | 超碰视屏| 91黄版| 17c在线 | 情侣作爱视频网站 | 99自拍视频在线观看 | 91免费版在线看 | 成人免费观看cn | 欧美123| 女人18毛片水真多 | 欧美xxxx在线 | 91免费精品视频 | 无码人妻丰满熟妇啪啪 | 亚洲精品在线视频 | 神马午夜51| 亚洲一区二区三区四区五区六区 | 色伊伊| 精品欧美一区二区精品少妇 | 国产图片一区 | 外国电影免费观看高清完整版 | 亚洲视频欧洲视频 | 久久伊人草 | 俺去俺来也在线www色官网 | 91国内揄拍国内精品对白 | 亚洲成av人片一区二区梦乃 | 精品无码久久久久久久久久 | 久久久国产精品成人免费 | 可以看的av网址 | 第一色网站 | 欧美一区二区日韩一区二区 | 国产精品永久 | 午夜爱爱网| 波多野结衣中文字幕一区 | 福利国产片 | 日韩美女视频在线 | 久久久久亚洲av成人网人人软件 | 国产91综合一区在线观看 | 色666| 成人免费毛片观看 | 靠逼视频网站 | 亚洲50p | 巨大胸大乳奶电影 | 真实乱视频国产免费观看 | 特级毛片a| 精久久 | 天天高潮夜夜爽 | 不卡的av电影 | 顶级毛片| 91精品国产综合久久福利 | 99re在线观看 | 911色 | 国产精品午夜视频 | 国产主播福利在线 | 在线观看亚洲色图 | 黄色精彩视频 | 色婷婷av一区二区三区大白胸 | 亚洲女人天堂成人av在线 | 天堂网一区 | 国产欧美综合一区二区三区 | 亚洲爆爽av | 色婷婷激情网 | 日本一区二区三区视频在线播放 | 亚洲日本成人在线观看 | 亲嘴扒胸摸屁股免费视频日本网站 | 黄色一级播放 | 日韩欧美高清视频 | 亚洲免费三级 | 色噜噜在线播放 | 色婷婷综合久久久久中文一区二区 | 亚洲一区二区三区成人 | 2021国产在线视频 | 国产无套在线观看 | 亚洲综合第一页 | 男女曰逼视频 | av日韩在线免费观看 | 成人av片免费看 | 亚洲AV无码久久精品色三人行 | 色哟哟无码精品一区二区三区 |