准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码:
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/epoll.h>
4 #include <sys/socket.h>
5 #include <signal.h>
6 #include <fcntl.h>
7 #include <map>
8 #include <errno.h>
9 #include <pthread.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 using namespace std;
13
14 struct conninfo{
15 int rfd;
16 int wfd;
17 //map<struct ipport, struct perrinfo> peer;
18 };
19
20 bool g_bRun;
21
22 struct conninfo g_ConnInfo;
23
24 void setnonblocking(int sock)
25 {
26 int opts;
27 opts = fcntl(sock, F_GETFL);
28 if(opts < 0)
29 {
30 printf("fcntl(sock, GETFL)");
31 exit(1);
32 }
33 opts = opts | O_NONBLOCK;
34 if(fcntl(sock, F_SETFL, opts) < 0)
35 {
36 printf("fcntl(sock, SETFL, opts)");
37 exit(1);
38 }
39 return ;
40 }
41
42 static void sig_pro(int signum)
43 {
44 printf("sig_pro recv signal: %d
", signum);
45 if(signum == SIGQUIT)
46 {
47 g_bRun = false;
48 }
49 }
50
51 void* AcceptThread(void* arg)
52 {
53 printf("accpet thread
");
54 return NULL;
55 }
56
57 void* ReadThread(void* arg)
58 {
59 printf("read thread
");
60 return NULL;
61 }
62
63 int main()
64 {
65 int ret;
66 int fd[2]; //pipe
67 pthread_t iAcceptThreadId;
68 pthread_t iReadThreadId;
69
70 struct sigaction sa;
71 sa.sa_flags = SA_RESTART;
72 sa.sa_handler = sig_pro;
73 sigaction(SIGINT, &sa, NULL);
74 sigaction(SIGUSR1, &sa, NULL);
75 sigaction(SIGUSR2, &sa, NULL);
76
77
78 g_bRun = true;
79 ret = pipe(fd);
80 if(ret < 0)
81 {
82 printf("main, pipe fall, %d %s
", ret, errno);
83 g_bRun = false;
84 return 0;
85 }
86
87 g_ConnInfo.rfd = fd[0];
88 g_ConnInfo.wfd = fd[1];
89
90 setnonblocking(g_ConnInfo.rfd);
91
92 pthread_attr_t attr;
93 pthread_attr_init(&attr);
94 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
95
96 ret = pthread_create(&iAcceptThreadId, &attr, AcceptThread, NULL);
97 if(ret != 0)
98 {
99 printf("main, create accept thread fail: %s
", errno);
100 g_bRun = false;
101 close(g_ConnInfo.rfd); //关闭管道
102 close(g_ConnInfo.wfd);
103 return 0;
104 }
105
106 ret = pthread_create(&iReadThreadId, &attr, ReadThread, NULL);
107 if(ret != 0)
108 {
109 printf("main, create read thread fail: %s
", errno);
110 g_bRun = false;
111 pthread_join(iAcceptThreadId, NULL);
112 close(g_ConnInfo.rfd);
113 close(g_ConnInfo.wfd);
114
115 return 0;
116 }
117
118 while(g_bRun)
119 {
120 sleep(1);
121 }
122
123 pthread_join(iAcceptThreadId, NULL); //收回线程的资源,销毁线程
124 pthread_join(iReadThreadId, NULL);
125 close(g_ConnInfo.rfd);
126 close(g_ConnInfo.wfd);
127
128 return 0;
129 }