准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码:
1 #include <stdio.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <signal.h>
#include <fcntl.h>
#include <map>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std; struct conninfo{
int rfd;
int wfd;
//map<struct ipport, struct perrinfo> peer;
}; bool g_bRun; struct conninfo g_ConnInfo; void setnonblocking(int sock)
{
int opts;
opts = fcntl(sock, F_GETFL);
if(opts < )
{
printf("fcntl(sock, GETFL)");
exit();
}
opts = opts | O_NONBLOCK;
if(fcntl(sock, F_SETFL, opts) < )
{
printf("fcntl(sock, SETFL, opts)");
exit();
}
return ;
} static void sig_pro(int signum)
{
printf("sig_pro recv signal: %d\n", signum);
if(signum == SIGQUIT)
{
g_bRun = false;
}
} void* AcceptThread(void* arg)
{
printf("accpet thread\n");
return NULL;
} void* ReadThread(void* arg)
{
printf("read thread\n");
return NULL;
} int main()
{
int ret;
int fd[]; //pipe
pthread_t iAcceptThreadId;
pthread_t iReadThreadId; struct sigaction sa;
sa.sa_flags = SA_RESTART;
sa.sa_handler = sig_pro;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL); g_bRun = true;
ret = pipe(fd);
if(ret < )
{
printf("main, pipe fall, %d %s\n", ret, errno);
g_bRun = false;
return ;
} g_ConnInfo.rfd = fd[];
g_ConnInfo.wfd = fd[]; setnonblocking(g_ConnInfo.rfd); pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); ret = pthread_create(&iAcceptThreadId, &attr, AcceptThread, NULL);
if(ret != )
{
printf("main, create accept thread fail: %s\n", errno);
g_bRun = false;
close(g_ConnInfo.rfd); //关闭管道
close(g_ConnInfo.wfd);
return ;
} ret = pthread_create(&iReadThreadId, &attr, ReadThread, NULL);
if(ret != )
{
printf("main, create read thread fail: %s\n", errno);
g_bRun = false;
pthread_join(iAcceptThreadId, NULL);
close(g_ConnInfo.rfd);
close(g_ConnInfo.wfd); return ;
} while(g_bRun)
{
sleep();
} pthread_join(iAcceptThreadId, NULL); //收回线程的资源,销毁线程
pthread_join(iReadThreadId, NULL);
close(g_ConnInfo.rfd);
close(g_ConnInfo.wfd); return ;
}