多线程模型
在多线程模型下,注意共享数据的同步,mutex/condition_variable/rw_lock等的使用,local thread storage的使用,另外,可以搭配线程池处理异步计算任务。在C++11中的线程库中已经提供了future相关的工具,合理地使用线程模型减少资源的同时,能获得不错的性能
//thread server
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_READ_CHUNK 2*1024*1024
#define KEEP_ALIVE 0
void run();
int main(int argc, char *argv[])
{
run();
return 0;
}
void error_exit()
{
perror("error");
exit(EXIT_FAILURE);
}
int do_read_and_write(int clientfd)
{
char read[MAX_READ_CHUNK];
ssize_t result;
result = recv(clientfd, read, sizeof(read), 0);
if (result<=0){
perror("error recv data");
return -1;
}
//write back
result = send(clientfd, read, result, 0);
if (result<=0){
perror("error send data");
return -1;
}
if(!KEEP_ALIVE)
close(clientfd);
return 0;
}
void *handle_client_socket(void *clientfd)
{
if (pthread_detach(pthread_self())!=0){
error_exit();
}
int client = *(int *)clientfd;
if (clientfd!=NULL){
free(clientfd);
clientfd = NULL;
}
if (do_read_and_write(client)<0){
error_exit();
}
//we set the thread detach,so no need call pthread_exit
//pthread_exit(NULL);
}
void run()
{
struct hostent *h;
h = gethostbyname("localhost");
if (!h){
error_exit();
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr = *(struct in_addr*)h->h_addr;
sin.sin_port = htons(8000);
int serverfd = socket(AF_INET, SOCK_STREAM, 0);
if (serverfd<0){
error_exit();
}
int reuse = 1;
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))){
error_exit();
}
socklen_t slen = sizeof(sin);
if (bind(serverfd, (struct sockaddr *)&sin, slen)<0){
error_exit();
}
if (listen(serverfd, 20)<0){
error_exit();
}
struct sockaddr_in client;
socklen_t slen_client = sizeof(client);
int clientfd;
pthread_t pt;
while(1){
clientfd = accept(serverfd, (struct sockaddr *)&client, &slen_client);
if (clientfd<0){
error_exit();
}
int *temp = (int *) malloc(sizeof(int));
*temp = clientfd;
if(pthread_create(&pt, NULL, handle_client_socket, temp)!=0){
error_exit();
}
}
}