几种并发服务器模型的实现:多线程,多进程,select,poll,epoll

http://www.cnblogs.com/wj9012/p/3879605.html


客户端使用select模型:

复制代码
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <errno.h>
  5 #include <sys/types.h>
  6 #include <sys/socket.h>
  7 #include <netinet/in.h>
  8 #include <arpa/inet.h>
  9 #include <sys/select.h>
 10 #include <signal.h>
 11 
 12 #define ERR_EXIT(m) \
 13     do { \
 14         perror(m);\
 15         exit(EXIT_FAILURE);\
 16     }while(0)
 17 
 18 static void do_client(int fd)
 19 {
 20     char recvbuf[MAXLINE + 1] = {0};
 21     char sendbuf[MAXLINE + 1] = {0};
 22 
 23     fd_set reade, ready;
 24     FD_ZERO(&reade);
 25     int fd_stdin = fileno(stdin);
 26     FD_SET(fd_stdin, &reade);
 27     FD_SET(fd, &reade);
 28     int fd_max = (fd_stdin > fd) ? fd_stdin : fd;
 29 
 30     int ret;
 31     while(1)
 32     {
 33         ready = reade;
 34         ret = select( fd_max+1, &ready, NULL, NULL, NULL);//轮询
 35         if(ret == -1)
 36         {
 37             if(errno == EINTR)
 38                 continue;
 39             ERR_EXIT("select");
 40         }else if(ret ==  0)
 41         {
 42             continue;
 43         }
 44 
 45         if(FD_ISSET(fd_stdin, &ready))
 46         {
 47             if(fgets(sendbuf, sizeof(sendbuf), stdin) == NULL)
 48             {
 49                 close(fd);
 50                break;
 51             }else
 52             {
 53                 if( -1 == write(fd, sendbuf, strlen(sendbuf)))
 54                     printf("write\n");
 55             }
 56         }
 57 
 58 
 59         if(FD_ISSET(fd, &ready))
 60         {
 61             int nread = read(fd, recvbuf, MAXLINE);
 62             if(nread < 0)
 63                 ERR_EXIT("read");
 64             if(nread == 0)//如果没接收到消息,打印关闭描述符,退出循环
 65             {
 66                 fprintf(stdout, "fd close\n");
 67                 break;
 68             }
 69             fprintf(stdout, "receive:%s", recvbuf);
 70         }
 71         memset(recvbuf, 0, sizeof recvbuf);
 72         memset(sendbuf, 0, sizeof sendbuf);
 73     }
 74 }
 75 void handle(int signum)
 76 {
 77 printf("sigpipe\n");
 78 }
 79 
 80 int main(int argc, const char *argv[])
 81 {
 82     signal(SIGPIPE, SIG_IGN);
 83     int fd = socket(AF_INET, SOCK_STREAM, 0);
 84     if(fd < 0)
 85         ERR_EXIT("socket");
 86 
 87     struct sockaddr_in cliaddr;
 88     cliaddr.sin_family = AF_INET;
 89     cliaddr.sin_port = htons(8888);
 90     cliaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
 91     socklen_t len = sizeof cliaddr;
 92 
 93     int ret ;
 94     if((ret = connect(fd, (struct sockaddr*)&cliaddr, len)) == -1)
 95     {
 96         close(fd);
 97         ERR_EXIT("connect");
 98     }
 99     do_client(fd);
100     close(fd);
101     return 0;
102 }
复制代码

 

 

1.并发多进程服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "rio.h"//封装了网络编程中的readn  writen   readline 3个函数
#include <signal.h>
#define ERR_EXIT(m) \
    do { \
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)
static void do_service(int fd)
{
    rio_t rt;
    rio_init(&rt, fd);
    char recvbuf[1024] = {0};
    int ret;
    while(1)
    {
        memset(recvbuf, 0, sizeof recvbuf);
        ret = rio_readline(&rt, recvbuf, 1024);
        if(ret == 0)  
        {
            close(fd);
            exit(EXIT_SUCCESS);
        }
        rio_writen(fd, recvbuf, strlen(recvbuf)) ;
    }
}
void handle(int signum)//对SIGCHLD信号的处理函数
{
    while(waitpid(-1, NULL, WNOHANG) > 0);
    return ;
}
int listenf();//封装了socket,bind,listen3个函数,返回需要监听的连接socket描述符
int main(int argc, const char *argv[])
{
    if(signal(SIGPIPE, SIG_IGN) == SIG_ERR)//对客户端关闭导致的信号的处理
        ERR_EXIT("signal_pipe");
    if(signal(SIGCHLD, handle) == SIG_ERR)//对子进程结束后资源的回收
        ERR_EXIT("signal_chld");
    int listenfd = listenf();
    struct sockaddr_in cliaddr;
    bzero(&cliaddr, sizeof(cliaddr));
    socklen_t cli_len = sizeof cliaddr;
    int clientfd;
    while(1)
    {
        clientfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cli_len);
        if(clientfd == -1) 
        {
            close(listenfd);
            ERR_EXIT("accept");
        }
         
        int pid;
        if((pid = fork()) == -1)
        {
            ERR_EXIT("fork");
        }else if(pid == 0)
        {
            close(listenfd);
            do_service(clientfd);
            exit(EXIT_SUCCESS);
        }
        close(clientfd);
    }
    close(listenfd);
    return 0;
}
int listenf()
{
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);//准备一个socketfd
    if(listenfd == -1 )
        ERR_EXIT("socket");
    int on = 1;
    if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)//setsockopt设置端口复用
    {
        close(listenfd);
        ERR_EXIT("setsockopt");
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(8888);
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    socklen_t len = sizeof(seraddr);
    if(bind(listenfd, (struct sockaddr*)&seraddr, len) == -1)//监听socket端口,
    {
        close(listenfd);
        ERR_EXIT("bind");
    }
    if(listen(listenfd, 6) == -1)
    {
        close(listenfd);
        ERR_EXIT("listen");
    }
    return listenfd;
}

 2.多线程服务器模型:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "rio.h"
#include <signal.h>
#include <pthread.h>
#define ERR_EXIT(m) \
    do { \
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)
static void do_service(int fd)
{
    rio_t rt;
    rio_init(&rt, fd);
    char recvbuf[1024] = {0};
    int ret;
    int rcnt = 0;
    while(1)
    {
        memset(recvbuf, 0, sizeof recvbuf);
        ret = rio_readline(&rt, recvbuf, 1024);
         if(ret == 0)
         {
         close(fd);
//         break;
          pthread_exit(NULL);
         }
         write(fd, recvbuf, strlen(recvbuf)) ;
    }
}
void handle(int signum)
{
    printf("hello\n");
}
void *pthread_func(void *arg)
{
    pthread_detach(pthread_self());
    int *q = (int*)arg;
   int p = *(int*)arg;
   free(q);
     do_service(p);
     close(p);
}
int listenf();
int main(int argc, const char *argv[])
{
    if(signal(SIGPIPE, handle) == SIG_ERR)
        ERR_EXIT("signal");
    int listenfd = listenf();
    struct sockaddr_in cliaddr;
    bzero(&cliaddr, sizeof(cliaddr));
    socklen_t cli_len = sizeof cliaddr;
    int clientfd;
    while(1)
    {
    clientfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cli_len);
    if(clientfd == -1) 
    {
        close(listenfd);
        ERR_EXIT("accept");
    }
    pthread_t tid;
    int *p = (int*)malloc(sizeof(int));
   *p = clientfd;
    pthread_create(&tid, NULL, pthread_func, p);
    }
    close(listenfd);
    return 0;
}
int listenf()
{
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);//准备一个socketfd
    if(listenfd == -1 )
        ERR_EXIT("listen");
    int on = 1;
    if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)//setsockopt设置端口复用
    {
        close(listenfd);
        ERR_EXIT("setsockopt");
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(8888);
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    socklen_t len = sizeof(seraddr);
    if(bind(listenfd, (struct sockaddr*)&seraddr, len) == -1)//监听socket端口,
    {
        close(listenfd);
        ERR_EXIT("bind");
    }
    if(listen(listenfd, 6) == -1)
    {
        close(listenfd);
        ERR_EXIT("listen");
    }
return listenfd;
}

 3.select服务器模型:

复制代码
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <unistd.h>
  5 #include <errno.h>
  6 #include <sys/types.h>
  7 #include <sys/stat.h>
  8 #include <sys/socket.h>
  9 #include <arpa/inet.h>
 10 #include <signal.h>
 11 #include <sys/select.h>
 12 #define MAXLEN 1024
 13 
 14 #define ERR_EXIT(m) \
 15     do { \
 16         perror(m);\
 17         exit(EXIT_FAILURE);\
 18     }while(0)
 19 
 20 int listenf();//封装了网络socket的socekt,bind,listen函数,返回监听的socket描述符
 21 void handle(int signum)//SIGPIPE(子进程结束)的信号的处理
 22 {
 23     printf("hello\n");
 24 }
 25 static void do_select(int);
 26 
 27 int main(int argc, const char *argv[])
 28 {
 29     if(signal(SIGPIPE, handle) == SIG_ERR)
 30         ERR_EXIT("signal");
 31     int listenfd = listenf();
 32     do_select(listenfd);
 33     close(listenfd);
 34     return 0;
 35 }
 36 
 37 int listenf()
 38 {
 39     int listenfd = socket(AF_INET, SOCK_STREAM, 0);//准备一个socketfd
 40     if(listenfd == -1 )
 41         ERR_EXIT("listen");
 42 
 43     int on = 1;
 44     if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)//setsockopt设置端口复用
 45     {
 46         close(listenfd);
 47         ERR_EXIT("setsockopt");
 48     }
 49 
 50     struct sockaddr_in seraddr;
 51     seraddr.sin_family = AF_INET;
 52     seraddr.sin_port = htons(8888);
 53     seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
 54     socklen_t len = sizeof(seraddr);
 55     if(bind(listenfd, (struct sockaddr*)&seraddr, len) == -1)//监听socket端口,
 56     {
 57         close(listenfd);
 58         ERR_EXIT("bind");
 59     }
 60 
 61     if(listen(listenfd, 6) == -1)
 62     {
 63         close(listenfd);
 64         ERR_EXIT("listen");
 65     }
 66     return listenfd;
 67 }
 68 
 69 void do_select(int fd)
 70 {
 71     //struct sockaddr_in cliaddr;
 72     //memset(&cliaddr, 0, sizeof(cliaddr));//此处不需要客户端的地址信息
 73     fd_set set;
 74     fd_set rset;
 75     FD_ZERO(&rset);
 76     FD_SET(fd, &rset);
 77     int nready;
 78     int fd_set[MAXLEN];
 79 
 80     int i;
 81     for(i = 0;i < MAXLEN; ++i)
 82         fd_set[i] = -1;
 83     fd_set[0] = fd;
 84 
 85     int maxi = fd;//初始最大轮询fd是监听的fd
 86     int  arrlen = 1;//表示数组长度
 87    
 88    char recvbuf[1024] = {0};
 89     while(1)
 90     {
 91         set = rset;
 92         nready = select(maxi+1, &set, NULL, NULL, NULL);
 93         if(nready == -1)
 94         {
 95             ERR_EXIT("select");
 96         }
 97         if(FD_ISSET(fd, &set))//查看书否有新的客户端请求
 98         {
 99             int clifd = accept(fd, NULL, NULL);
100             if(clifd == -1)
101                 ERR_EXIT("accept");
102             for(i = 1; i < MAXLEN; ++i)
103             { if(fd_set[i] == -1)
104                 {
105                     fd_set[i] = clifd;
106                     break;
107                 }
108             }
109             FD_SET(clifd, &rset);
110             if(clifd > maxi)
111                 maxi = clifd;
112             arrlen++;
113             --nready;
114         }
115 
116         for(i = 1; i < arrlen; ++i)//轮询数据连接
117         {
118             int set_fd = fd_set[i];
119          if(FD_ISSET(set_fd, &set))
120          {
121             int n = read(set_fd, recvbuf, 1024);
122             if(n == -1)
123                 ERR_EXIT("read");
124             else if(n == 0)//客户端退出,
125             {
126               FD_CLR(set_fd, &rset);
127               close(set_fd);
128               fd_set[i] = -1;
129               arrlen--;
130             }
131             write(set_fd, recvbuf, strlen(recvbuf));
132                memset(recvbuf, 0, 1024);
133          if(--nready < 0)
134              break;
135          }
136         }
137     }
138 }
复制代码


4

复制代码
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <unistd.h>
  5 #include <errno.h>
  6 #include <sys/types.h>
  7 #include <sys/stat.h>
  8 #include <sys/socket.h>
  9 #include <arpa/inet.h>
 10 #include <signal.h>
 11 #include <poll.h>
 12 #define MAXLEN 1024
 13 
 14 #define ERR_EXIT(m) \
 15     do { \
 16         perror(m);\
 17         exit(EXIT_FAILURE);\
 18     }while(0)
 19 
 20 static void do_service(int);
 21 int listenf();
 22 void handle(int signum)
 23 {
 24     printf("hello\n");
 25 }
 26 static void do_poll(int);
 27 
 28 int main(int argc, const char *argv[])
 29 {
 30     if(signal(SIGPIPE, handle) == SIG_ERR)
 31         ERR_EXIT("signal");
 32     int listenfd = listenf();
 33     do_poll(listenfd);
 34     close(listenfd);
 35     return 0;
 36 }
 37 
 38 int listenf()
 39 {
 40     int listenfd = socket(AF_INET, SOCK_STREAM, 0);//准备一个socketfd
 41     if(listenfd == -1 )
 42         ERR_EXIT("listen");
 43 
 44     int on = 1;
 45     if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)//setsockopt设置端口复用
 46     {
 47         close(listenfd);
 48         ERR_EXIT("setsockopt");
 49     }
 50 
 51     struct sockaddr_in seraddr;
 52     seraddr.sin_family = AF_INET;
 53     seraddr.sin_port = htons(8888);
 54     seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
 55     socklen_t len = sizeof(seraddr);
 56     if(bind(listenfd, (struct sockaddr*)&seraddr, len) == -1)//监听socket端口,
 57     {
 58         close(listenfd);
 59         ERR_EXIT("bind");
 60     }
 61 
 62     if(listen(listenfd, 6) == -1)
 63     {
 64         close(listenfd);
 65         ERR_EXIT("listen");
 66     }
 67     return listenfd;
 68 }
 69 
 70 void do_poll(int fd)
 71 {
 72     struct pollfd pfd[MAXLEN];//设置的最大连接数,存放结构体信息
 73     char recvbuf[1024] = {0};
 74     int i;
 75     for(i = 0; i < MAXLEN; ++i)
 76         pfd[i].fd = -1;
 77 
 78     pfd[0].fd = fd;
 79     pfd[0].events = POLLIN;//将监听连接的描述符防止数组开头
 80 
 81     int nready;
 82     int maxi = 0;
 83     while(1)
 84     {
 85         nready = poll(pfd, maxi+1, -1);//轮询的是有效数组长度,不能少1
 86         if(nready == -1)
 87         {
 88             ERR_EXIT("select");
 89         }
 90 
 91         if(pfd[0].revents & POLLIN)//有客户端请求连接
 92         {
 93             int clifd = accept(fd, NULL, NULL);
 94             if(clifd == -1)
 95                 ERR_EXIT("accept");
 96             for(i = 1; i < MAXLEN; ++i)
 97             { 
 98                 if(pfd[i].fd == -1)
 99                 {
100                     pfd[i].fd = clifd;
101                     pfd[i].events = POLLIN;
102                     break;
103                 }
104             }
105             if(i > maxi)
106                 maxi = i;  
107             --nready;
108         }
109 
110         for(i = 1; i <= maxi; ++i)
111         {
112             if(pfd[i].fd == -1)
113                 continue;
114 
115             if( pfd[i].revents & POLLIN)
116             {
117                 int n = read(pfd[i].fd, recvbuf, 1024);
118                 if(n == -1)
119                     ERR_EXIT("read");
120                 else if(n == 0)//客户端退出,则从集合中清除
121                 {
122                     printf("%d close\n", pfd[i].fd);
123                     close(pfd[i].fd); 
124                     pfd[i].fd = -1;
125                     continue;
126                 }
127                 write(pfd[i].fd, recvbuf, strlen(recvbuf));
128                 memset(recvbuf, 0, 1024);
129 
130                 if(--nready < 0)
131                     break;
132             }
133         }
134     }
135 }
复制代码

5.epoll服务器模型:

复制代码
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <unistd.h>
  5 #include <errno.h>
  6 #include <sys/types.h>
  7 #include <sys/stat.h>
  8 #include <sys/socket.h>
  9 #include <arpa/inet.h>
 10 #include <signal.h>
 11 #include <sys/epoll.h>
 12 #define MAXLEN 1024
 13 
 14 #define ERR_EXIT(m) \
 15     do { \
 16         perror(m);\
 17         exit(EXIT_FAILURE);\
 18     }while(0)
 19 
 20 int listenf();
 21 static void do_epoll(int);
 22 
 23 int main(int argc, const char *argv[])
 24 {
 25     int listenfd = listenf();
 26     do_epoll(listenfd);
 27     close(listenfd);
 28     return 0;
 29 }
 30 
 31 int listenf()
 32 {
 33     int listenfd = socket(AF_INET, SOCK_STREAM, 0);//准备一个socketfd
 34     if(listenfd == -1 )
 35         ERR_EXIT("listen");
 36 
 37     int on = 1;
 38     if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)//setsockopt设置端口复用
 39     {
 40         close(listenfd);
 41         ERR_EXIT("setsockopt");
 42     }
 43 
 44     struct sockaddr_in seraddr;
 45     seraddr.sin_family = AF_INET;
 46     seraddr.sin_port = htons(8888);
 47     seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
 48     socklen_t len = sizeof(seraddr);
 49     if(bind(listenfd, (struct sockaddr*)&seraddr, len) == -1)//监听socket端口,
 50     {
 51         close(listenfd);
 52         ERR_EXIT("bind");
 53     }
 54 
 55     if(listen(listenfd, 6) == -1)
 56     {
 57         close(listenfd);
 58         ERR_EXIT("listen");
 59     }
 60     return listenfd;
 61 }
 62 
 63 void do_epoll(int fd)
 64 {
 65     char recvbuf[MAXLEN] = {0};
 66     int epollfd = epoll_create(2048);//设置的最大连接数
 67     if(epollfd == -1)
 68         ERR_EXIT("epoll_create");
 69 
 70     struct epoll_event ev;
 71     ev.data.fd = fd;
 72     ev.events = EPOLLIN;
 73     if(epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1)//加入轮询
 74                  ERR_EXIT("epoll_ctl_add");
 75 
 76     struct epoll_event events[2048];//数组在epoll_wait返回结果的时候使用
 77     int ret;
 78     int i;//在下面while的for循环中遍历使用
 79     int rfd;
 80     int clientfd;
 81     int nread;
 82     while(1)
 83     {
 84         ret = epoll_wait(epollfd, events, 2048, -1);
 85         if(ret == -1)
 86             ERR_EXIT("epoll_wait");
 87 
 88         for(i = 0; i < ret; ++i )
 89         {
 90             rfd = events[i].data.fd;
 91             if(rfd == fd)
 92             {
 93                 if((clientfd = accept(fd, NULL, NULL)) == -1)
 94                 ERR_EXIT("accept");
 95                 ev.data.fd = clientfd;
 96                 ev.events = EPOLLIN;
 97                 if(epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev) == -1)
 98                     ERR_EXIT("epoll_ctl");
 99             }else
100             {
101                 int nread = read(rfd, recvbuf, MAXLEN);
102                 if(nread == -1)
103                 {
104                     if(errno == EINTR)
105                         continue;
106                     ERR_EXIT("read");
107                 }else if( nread == 0)//客户端退出,从epoll轮询中删除
108                 {
109                     printf("%d fd close\n", rfd);
110                     ev.data.fd = rfd;
111                     ev.events = EPOLLIN;
112                     if(epoll_ctl(epollfd, EPOLL_CTL_DEL, rfd, &ev) == -1)
113                         ERR_EXIT("epoll_ctl");
114                 }else
115                 {
116                     if(write(rfd, recvbuf, strlen(recvbuf)) == -1)
117                         ERR_EXIT("write");
118                     memset(recvbuf, 0, MAXLEN);
119                 }
120             }
121         }
122     }
123     close(epollfd);
124 }
复制代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)

http://blog.csdn.net/zzyoucan/article/details/9235685 信号&#xff1a;信号是unix中最古老的进程通信的一种方式&#xff0c;他是软件层次上对中断机制的模拟&#xff0c;是一种异步通信方式&#xff0c;信号可以实现用户空间进程和内核空间进程的交互&#xff0c;内核进程…

Linux epoll模型

http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html 定义&#xff1a; epoll是Linux内核为处理大批句柄而作改进的poll&#xff0c;是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利…

Linux IO模式及 select、poll、epoll详解

https://segmentfault.com/a/1190000003063859 同步IO和异步IO&#xff0c;阻塞IO和非阻塞IO分别是什么&#xff0c;到底有什么区别&#xff1f;不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。一 概念…

mysql思维导图

后期会不断进行更新

C++第一节课

C数据类型 几个概念 命名空间是C标准库引入的,其中命名空间可以解决变量冲突问题,当出现局部变量和全局变量同名的时候, 局部变量优先被访问.同时命名空间的格式如同一下代码 namespace name1 { int a 0; }namespace name2 { int a 2; } 注意C中的所有组件都是在一个叫做s…

【C/C++】关键字static

http://blog.csdn.net/woxiaohahaa/article/details/51014224 参考自&#xff1a;http://www.cnblogs.com/biyeymyhjob/archive/2012/07/19/2598815.html &#xff08;华山大师兄&#xff09; 这里我们只讨论了C语言的static 首先我们回顾一下各种变量在内存中的位置&#xff1…

IO多路复用之epoll总结

http://www.cnblogs.com/Anker/p/3263780.html 1、基本知识 epoll是在2.6内核中提出的&#xff0c;是之前的select和poll的增强版本。相对于select和poll来说&#xff0c;epoll更加灵活&#xff0c;没有描述符限制。epoll使用一个文件描述符管理多个描述符&#xff0c;将用户关…

3_V1-类和对象 -- 默认成员函数

定义一个日期类 #include <iostream> #include <assert.h> using namespace std;class Date { public:void Display(); private:int _year;int _month;int _day; }; 注意: 在定义一个类的时候往往会将其成员变量定义为私有,成员函数定义为公有.这是为了达到软件…

HDU - 2973威尔逊定理

核心问题就是那个等式 我们观察到等式可以写成(n-1)!-1/n-[(n-1)!/n]的形式&#xff0c;这样就应该联想到威尔逊定理了。 回顾一下威尔逊定理的内容&#xff1a;当且仅当n为素数的时候n|(n-1)!-1&#xff0c;n为合数且大于4的时候n|(n-1)!【参见威尔逊定理的证明】 对于这个…

linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题

http://blog.csdn.net/jnu_simba/article/details/9129939 一、posix 条件变量 一种线程间同步的情形&#xff1a;线程A需要等某个条件成立才能继续往下执行&#xff0c;现在这个条件不成立&#xff0c;线程A就阻塞等待&#xff0c;而线程B在执行过程中使这个条件成立了&#x…

3-V2-类和对象 -- const内联 静态成员 友元

const修饰成员函数 在成员函数后面加一个const, const修饰this指针指向的对象, 保证调用这个const成员函数的对象在函数内不会被改变 注意:成员函数如果不修改成员变量,则加上const,成员函数如果要修改成员变量,此时就不能给其加上const修饰了 1.const对象不能调用非const…

C语言 二级指针内存模型混合实战

http://www.cnblogs.com/zhanggaofeng/p/5485833.html //二级指针内存模型混合实战 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h>//将内存模型①和内存模型②的数据拷贝到内存模型③ char ** threemodel(ch…

Linux 网络编程八(epoll应用--大并发处理)

http://www.cnblogs.com/zhanggaofeng/p/5901316.html //头文件 pub.h #ifndef _vsucess#define _vsucess#ifdef __cplusplus extern "C" {#endif //服务器创建socket int server_socket(int port);//设置非阻塞 int setnonblock(int st);//接收客户端socket int ser…

【数据结构与算法】内部排序之三:堆排序(含完整源码)

转载请注明出处&#xff1a;http://blog.csdn.net/ns_code/article/details/20227303 前言 堆排序、快速排序、归并排序&#xff08;下篇会写这两种排序算法&#xff09;的平均时间复杂度都为O&#xff08;n*logn&#xff09;。要弄清楚堆排序&#xff0c;就要先了解下二叉堆这…

模线性方程(中国剩余定理+扩展中国剩余定理)

已知一系列除数和模数,求最小的满足条件的数 我们先考虑一般的情况&#xff0c;即模数不互质。&#xff08;扩展中国剩余定理&#xff09; 我们考虑两个方程的情况 x%MR xk1∗MRxk1 * MRxk1∗MR x%mr xk2∗mrxk2 * mrxk2∗mr 所以k1∗MRk2∗mrk1 * MRk2 * mrk1∗MRk2∗mr 即…

【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)

http://blog.csdn.net/hanjing_1995/article/details/51539578 使用两个栈实现一个队列 思路一&#xff1a; 我们设定s1是入栈的&#xff0c;s2是出栈的。 入队列&#xff0c;直接压到s1即可 出队列&#xff0c;先把s1中的元素倒入到s2中&#xff0c;弹出s2中的栈顶元素&#x…

C++::探索对象模型

前面我们已经知道, 在没有虚函数的时候, 对象的大小就是对应的成员变量的大小, 而成员函数不会占用对象的空间, 今天我们来讨论一下, 当类中定义了虚函数的时候, 此时对象的大小以及对象模型 非继承下的对象模型 class Base { public:virtual void func1(){cout << &qu…

软件测试相关概念

什么叫软件测试 软件测试就是测试产品没有错误,同时又证明软件是可以正确运行的 测试和调试的区别 调试一般都在开发期间 ,测试是伴随着整个软件的生命周期, 调试是发现程序中问题并且解决问题, 测试是发现程序中的缺陷 软件测试的目的和原则 目的:验证软件有没有问题 原…

C++静态成员函数访问非静态成员的几种方法

https://www.cnblogs.com/rickyk/p/4238380.html 大家都知道C中类的成员函数默认都提供了this指针&#xff0c;在非静态成员函数中当你调用函数的时候&#xff0c;编译器都会“自动”帮你把这个this指针加到函数形参里去。当然在C灵活性下面&#xff0c;类还具备了静态成员和静…

HDU2683——欧拉完全数

题目要求符合等式的数&#xff0c;我们首先要做的就是分析这个数&#xff1a; 对于这个等式&#xff0c;我们可能什么都看不出来&#xff0c;左边很难化简的样子&#xff0c;所以我们就要想到通过变化怎么样把右边化成和左边形式差不多的样子。结合组合数我们想到二项式定理&am…