參考:linux高性能server编程。作者:游双
程序简单介绍:该程序用了共享内存来实现进程间的同步,因为仅仅是同一时候读取共享内存。所以没实用到锁。该程序的功能是server监听网络连接,当有一个client连接时,server创建一个子进程处理该连接。
每一个子进程仅仅负责自己的client以及和父进程通信。当子进程从client读取数据后,把数据放到共享内存上,每一个子进程在共享内存上有自己的一段空间。因此不会出现同一时候写。
放上去后通知父进程,说:共享内存上有新数据到达了,然后父进程通知其它子进程,去到该位置读取数据,把数据发送到自己的client。实现了群聊的效果。该程序对于多进程编程的刚開始学习的人是个不错的样例,写下来是为了让自己熟悉一下。
server代码:编译的时候须要加上 -lrt选项
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <sys/epoll.h> #include <signal.h> #include <sys/wait.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #define USER_LIMIT 5 #define BUFFER_SIZE 1024 #define FD_LIMIT 65535 #define MAX_EVENT_NUMBER 1024 #define PROCESS_LIMIT 65536 /* 处理一个客户端连接的必要数据 */ struct client_data { sockaddr_in address; int connfd; /* 客户端的fd */ pid_t pid; /* 处理这个连接的子进程的pid */ int pipefd[2]; /* 和父进程通信用的管道 */ }; int sig_pipefd[2];//当有信号发生时。用于父进程自己的通信 char* share_mem; int user_count = 0; //当前客户的数量 client_data* users = 0 ; int* sub_process = 0; static const char* shm_name = "/my_share_memory"; int maxevents = 100; bool stop_child = false; void setnonblock(int fd) { int flag = fcntl(fd,F_GETFL); assert(flag != -1); fcntl(fd,F_SETFL,flag | O_NONBLOCK); } void addfd(int epollfd,int fd) { epoll_event ee; ee.data.fd = fd; ee.events = EPOLLIN | EPOLLET; epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ee); setnonblock(fd); } void sig_handler(int sig) { int save_errno = errno; int msg = sig; send(sig_pipefd[1],(char*)&msg,1,0); errno = save_errno;//恢复错误值 } void child_sig_handler(int sig) { stop_child = true; } void addsig(int sig,void (*handler)(int),bool restart = true) { struct sigaction sa; memset(&sa,'