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

最近在读《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 16384

static 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 4096



void 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值