1、線程池網(wǎng)絡(luò)服務(wù)
成都創(chuàng)新互聯(lián)是一家專業(yè)提供朝陽企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、成都網(wǎng)站制作、H5頁面制作、小程序制作等業(yè)務(wù)。10年已為朝陽眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
:針對(duì)多線程網(wǎng)絡(luò)服務(wù)模式的一些不足之處而提出的改進(jìn)模式。
池是一個(gè)很重要的概念,其基本理念是:先創(chuàng)建一批資源,當(dāng)有用戶到來時(shí),直接分配以創(chuàng)建好的資源,它的主要目的是減少系統(tǒng)在頻繁創(chuàng)建資源時(shí)的開銷。
實(shí)現(xiàn)原理:主服務(wù)線程創(chuàng)建既定數(shù)量的服務(wù)線程,當(dāng)有客戶端到來時(shí),則從線程池中找出空閑的服務(wù)線程,為其服務(wù),服務(wù)完畢后,線程不進(jìn)行釋放,重新放回線程池;若當(dāng)前線程池已滿,則將當(dāng)前的客戶端加入等待隊(duì)列。
模型如下:
2、代碼實(shí)現(xiàn)
同樣用處理整數(shù)運(yùn)算來模擬線程池的并發(fā)處理
(1)、utili.h
#include#include #include #include #include #include #include #include #define SERVER_PORT 8090 #define SERVER_IP "127.0.0.1" #define LISTEN_QUEUE 5 #define BUFFER_SIZE 255 #define CMD_SIZE 20 #define THREAD_POOL_NUM 5 typedef enum{ADD,SUB,MUL,DIV,MOD, QUIT}OPER_TYPE; typedef enum{IDEL, BUSY}THREAD_TAG; typedef struct OperStruct{ int op1; int op2; OPER_TYPE oper; }OperStruct;
(2)、ser.c
#include"../utili.h" typedef struct PoolStruct{ int sockConn; THREAD_TAG flag; }PoolStruct; typedef PoolStruct threadpool[THREAD_POOL_NUM]; threadpool pool; pthread_t tid[THREAD_POOL_NUM]; void* Thread_Handler(void *arg); void* Thread_Handler(void *arg){ int index = *(int *)arg; printf("[%d] thread start up.\n", index); OperStruct op; int result; while(1){ if(pool[index].flag == BUSY){ printf("[%d] thread start wroking.\n", index); int res = recv(pool[index].sockConn, &op, sizeof(op), 0); if(res == -1){ printf("recv data fail.\n"); continue; } if(op.oper == ADD){ result = op.op1 + op.op2; }else if(op.oper == SUB){ result = op.op1 - op.op2; }else if(op.oper == MUL){ result = op.op1 * op.op2; }else if(op.oper == DIV){ result = op.op1 / op.op2; }else if(op.oper == QUIT){ break; } res = send(pool[index].sockConn, &result, sizeof(result), 0); if(res == -1){ printf("send data fail.\n"); continue; } }else{ printf("[%d] thread sleep.\n",index); sleep(1); } } close(pool[index].sockConn); pthread_exit(0); } int main(void){ int sockSer = socket(AF_INET, SOCK_STREAM, 0); if(sockSer == -1){ perror("socket"); return -1; } struct sockaddr_in addrSer, addrCli; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); socklen_t len = sizeof(struct sockaddr); int res = bind(sockSer, (struct sockaddr*)&addrSer, len); if(res == -1){ perror("bind"); close(sockSer); return -1; } listen(sockSer, LISTEN_QUEUE); int i; for(i=0; i%s\n", inet_ntoa(addrCli.sin_addr)); printf("Client Port:>%d\n",ntohs(addrCli.sin_port)); } for(i=0; i (3)、cli.c
#include"utili.h" void InputData(OperStruct *pt); void InputData(OperStruct *pt){ printf("please input op1 and op2 : "); scanf("%d %d", &(pt->op1), &(pt->op2)); } //Cli int main(void){ int sockCli = socket(AF_INET, SOCK_STREAM, 0); if(sockCli == -1){ perror("socket"); return -1; } struct sockaddr_in addrSer; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); socklen_t len = sizeof(struct sockaddr); int res = connect(sockCli, (struct sockaddr*)&addrSer, len); if(res == -1){ perror("connect"); close(sockCli); return -1; }else{ printf("Client Connect Server Success.\n"); } char cmd[2]; OperStruct op; int result; while(1){ printf("Please input operator : "); scanf("%s",cmd); if(strcmp(cmd, "+") == 0){ op.oper = ADD; InputData(&op); }else if(strcmp(cmd,"-") == 0){ op.oper = SUB; InputData(&op); }else if(strcmp(cmd,"*") == 0){ op.oper = MUL; InputData(&op); }else if(strcmp(cmd,"/") == 0){ op.oper = DIV; InputData(&op); }else if(strcmp(cmd, "quit") == 0){ op.oper = QUIT; }else{ printf("Cmd invalid.\n"); } res = send(sockCli, &op, sizeof(op), 0); if(res == -1){ printf("send data fail.\n"); continue; } if(op.oper == QUIT) break; res = recv(sockCli, &result, sizeof(result), 0); if(res == -1){ printf("recv data fail.\n"); continue; } printf("result = %d\n", result); } close(sockCli); return 0; }運(yùn)行結(jié)果
客戶端1
客戶端2
3、分析總結(jié)
(1)、其優(yōu)點(diǎn):性能高效
(2)、可能存在的問題:新用戶如果在等待隊(duì)列里耗時(shí)過長(zhǎng),會(huì)影響用戶體驗(yàn),針對(duì)此問題,改進(jìn)方案如下:
a、動(dòng)態(tài)創(chuàng)建新的服務(wù)線程,服務(wù)結(jié)束后,該線程加入線程池,這種改進(jìn)的好處是,用戶體驗(yàn)得到提升,潛在問題是,在長(zhǎng)時(shí)間,大規(guī)模的并發(fā)用戶狀態(tài)下,線程會(huì)產(chǎn)生很多,最終會(huì)因?yàn)橘Y源消耗過多,系統(tǒng)退出。
b、增加一個(gè)線程資源回收機(jī)制,當(dāng)線程池的規(guī)模達(dá)到一定程度或滿足某種既定規(guī)則時(shí),會(huì)主動(dòng)殺死一些線程,以達(dá)到系統(tǒng)穩(wěn)定和用戶體驗(yàn)之間折中。
模型分析
當(dāng)有客戶端來,有2種做法,i>、創(chuàng)建線程為其服務(wù);ii>、加入等待隊(duì)列;這2種都不太合適,采用折中法,有一個(gè)上限值,即就是規(guī)定一個(gè)創(chuàng)建線程的最大數(shù),當(dāng)來一個(gè)用戶,還沒達(dá)到線程最大數(shù)時(shí),為其創(chuàng)建線程,若達(dá)到了,則加入等待隊(duì)列;
對(duì)線程資源的回收:i>、立馬回收,ii>、暫時(shí)不回收;當(dāng)空閑的線程數(shù)達(dá)到某一下限值時(shí),此時(shí)再將線程回收;
名稱欄目:線程池網(wǎng)絡(luò)服務(wù)
標(biāo)題來源:http://weahome.cn/article/jhohch.html