代码路径:https://github.com/prophetss/epoll-event
之前实现了一个简单高效的hashtable(点这里),之后一直想利用它再延伸一些功能,后来偶然看到一个hashtable与epoll事件的结合感觉效率很高所以自己尝试着实现了下。大体思想是将epoll接到的每一个服务请求存储到hashtable里来管理,每一个请求都可以设置独立的回调函数。具体可以先看代码,注释已经写得很详细。代码实现了一个简单实例,由于条件有限,client端我是fork了大量子进程来模仿高并发请求。性能测试我这几天有时间再搞下,大概试了下1s几十万次请求应该是可以的。暂时先写到这里,下面先贴一个client的源码充下大小..
1 #include <unistd.h> 2 #include <sys/mman.h> 3 #include <netinet/in.h> 4 #include <semaphore.h> 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <arpa/inet.h> 8 #include <fcntl.h> 9 #include <wait.h> 10 #include <string.h> 11 #include <netdb.h> 12 #include <stdlib.h> 13 #include "error.h" 14 15 16 /*进程共享文件用于统计创建进程个数*/ 17 #define PFILE_NAME "count" 18 19 20 struct shared { 21 sem_t mutex; /*信号量用于加锁*/ 22 int count; /*进程个数*/ 23 } shared; 24 25 26 void request(const char *server_ip, int server_port) 27 { 28 struct sockaddr_in client_addr; 29 bzero(&client_addr, sizeof(client_addr)); 30 client_addr.sin_family = AF_INET; 31 client_addr.sin_addr.s_addr = INADDR_ANY; 32 client_addr.sin_port = htons(0); 33 34 int client_socket = socket(AF_INET, SOCK_STREAM, 0); 35 if(client_socket < 0) sys_exit_throw("create client socket fail"); 36 37 struct sockaddr_in server_addr; 38 bzero((char *)&server_addr, sizeof(server_addr)); 39 40 server_addr.sin_family = AF_INET; 41 42 struct hostent *server = gethostbyname(server_ip); 43 if(!server) sys_exit_throw("fail to get host name"); 44 45 bcopy((char *)server->h_addr, (char *)&server_addr.sin_addr.s_addr, server->h_length); 46 47 server_addr.sin_port = htons(server_port); 48 socklen_t server_addr_len = sizeof(server_addr); 49 50 if(connect(client_socket, (struct sockaddr*) &server_addr, server_addr_len) == -1 ) { 51 sys_exit_throw("connent to server fail"); 52 } 53 54 int pid = getpid(); 55 56 char content[64] = {0}; 57 sprintf(content, "%s, pid:%d", "i am client!", pid); 58 59 send(client_socket, content, strlen(content), 0); 60 61 close(client_socket); 62 } 63 64 /* 65 参数1为serverip,参数2为server端口号 66 */ 67 int main(int argc,char *argv[]) 68 { 69 if(argc != 3) exit_throw("parameter error!\n"); 70 71 char *server_ip = argv[1]; 72 int server_port = atoi(argv[2]); 73 74 struct shared *psh; 75 76 /*创建共享文件*/ 77 int fd = open(PFILE_NAME, O_RDWR | O_CREAT, 0666); 78 /*初始化*/ 79 write(fd, &shared, sizeof(struct shared)); 80 /*映射内存*/ 81 psh = mmap(NULL, sizeof(struct shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 82 close(fd); 83 84 sem_init(&psh->mutex, 1, 1); 85 86 /*初始进程+1*/ 87 psh->count++; 88 89 int i, status; 90 for (i = 0; i < 10; i++) { 91 pid_t fpid = fork(); 92 if (0 == fpid) { 93 sem_wait(&psh->mutex); 94 psh->count++; 95 printf("%d processes have created!\n", psh->count); 96 sem_post(&psh->mutex); 97 request(server_ip, server_port); 98 } 99 else if (fpid > 0) { 100 request(server_ip, server_port); 101 wait(&status); 102 } 103 else 104 sys_exit_throw("fork error!"); 105 } 106 107 return 0; 108 }
原文地址:https://www.cnblogs.com/prophet-ss/p/9180977.html
时间: 2024-10-26 01:11:04