linux下利用线程池构建高并发server

来源:互联网 发布:甬商贷网络借贷 编辑:程序博客网 时间:2024/06/06 03:20

最近在读《UNIX网络编程》,但是只读书而不实践是远远不行的。在阅读完线程池那块之后,自己动手写了一个简单的基于线程池的server/client程序。程序如下:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<pthread.h>int clifd[32];#define thread_num 10#define MAXLINE 16384static int iput = 0;static int iget = 0;pthread_mutex_t clifd_mutex;pthread_cond_t new_conn = PTHREAD_COND_INITIALIZER;void child_serv(int sock_fd){char buf[MAXLINE];int nread;int nwrite;while((nread=read(sock_fd,buf,MAXLINE))>0){nwrite = write(sock_fd,buf,nread);printf("server write %d bytes to client\n",nwrite);}if(nread<0)printf("read error\n");}void * thread_func(){int connfd;while(1){pthread_mutex_lock(&clifd_mutex);while(iget==iput)pthread_cond_wait(&new_conn,&clifd_mutex);connfd=clifd[iget];iget++;pthread_mutex_unlock(&clifd_mutex);child_serv(connfd);close(connfd);  }}int main(int argc, char ** argv){int listen_fd,conn_fd;socklen_t client_len;pthread_t thread_id[thread_num];int i=0;struct sockaddr_in serv_addr,client_addr;for(i=0;i<thread_num;i++){pthread_create(&thread_id[i],NULL,&thread_func,NULL);}if((listen_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1){printf("socket create error: %s\n",strerror(errno));exit(0);}memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(6666);if(bind(listen_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1){printf("bind error: %s\n",strerror(errno));exit(0);}if(listen(listen_fd,10)==-1){printf("listen error: %s\n",strerror(errno));exit(0);}while(1){conn_fd = accept(listen_fd,NULL,NULL);pthread_mutex_lock(&clifd_mutex);clifd[iput] = conn_fd;iput++;pthread_cond_signal(&new_conn);pthread_mutex_unlock(&clifd_mutex);}return 0;}
server端在启动进程的时候会创建10个线程,这10个线程就构成了线程池。

当连接数组clifd为空的时候,这些线程就会睡眠。当有新的连接到来后,主线程会发送信号到条件变量信号,这时候在线程池中就会有线程被唤醒,该线程即可去处理客户的请求。


client端的程序如下:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<pthread.h>#define MAXLINE 4096void str_cli(FILE * fp,int sock_fd){char sendline[MAXLINE],recvline[MAXLINE];while(fgets(sendline,MAXLINE,fp)!=NULL){write(sock_fd,sendline,strlen(sendline));if(read(sock_fd,recvline,MAXLINE)==0)printf("read error\n");fputs(recvline,stdout);}}int main(int argc, char ** argv){int sock_fd;struct sockaddr_in serv_addr;char recvline[4096], sendline[4096];if((sock_fd = socket(AF_INET,SOCK_STREAM,0))<0){printf("create socket error: %s\n",strerror(errno));exit(0);}memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(6666);if(inet_pton(AF_INET,argv[1],&serv_addr.sin_addr,sizeof(serv_addr))<0){printf("inet_pton error: %s\n",strerror(errno));exit(0);}if(connect(sock_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){printf("connect error: %s\n",strerror(errno));exit(0);}str_cli(stdin,sock_fd);return 0;}




0 0