///
/// @file Lock.h
/// @brief
/// @author guozhiming
/// @date 2007-04-11
///
#ifndef __LOCK__
#define __LOCK__
#include "def.h"
//定义了信号量锁,还有读写锁;话说我用qt开发,这些锁qt里面都有。可以直接拿来用了
/// @brief 锁的基本操作 1:读操作的时候读锁可以并发 2:写操作的时候,独占操作
class G_Lock
{
public:
/// @brief 构造函数初始化互斥锁 , 条件变量
G_Lock();
/// @brief 析构函数释放互斥锁,和条件变量
~G_Lock();
/// @brief 读锁 readCounter++ , 锁住readCounter
void rLock();
/// @brief 解锁 readCounter-- , 如果readCounter = 0 , pthread_cond_signal通知
void unrLock();
/// @brief 写锁 如果readCounter不为0一直 pthread_cond_wait等待下去
void wLock();
/// @brief 解锁
void unwLock();
private:
pthread_mutex_t r_Mutex; ///读锁 ,锁住readCounter
pthread_mutex_t w_Mutex; ///锁住同步资源
unsigned long readCounter; ///条件变量如果为0通知(pthread_cond_signal)
pthread_cond_t condReadCounter;
};
#endif
///
/// @file Lock.cpp
/// @brief
/// @author guozhiming
/// @date 2007-04-11
//现在是2013年,这家伙07年就写得这代码,我现在看,是否落后呢?
///
#include "Lock.h"
G_Lock::G_Lock()
{
pthread_mutex_init(&r_Mutex , NULL);
pthread_mutex_init(&w_Mutex , NULL);
pthread_cond_init(&condReadCounter , NULL);
readCounter = 0;
}
G_Lock::~G_Lock()
{
pthread_mutex_destroy(&r_Mutex);
pthread_mutex_destroy(&w_Mutex);
pthread_cond_destroy(&condReadCounter);
}
void G_Lock::rLock()
{
//读写都是配套出现的,没有现成的c库吗?要自己写。读的时候不许写,读靠一个信号量,最大允许多少人同时读。。。
pthread_mutex_lock(&w_Mutex); //防止于写操作冲突
pthread_mutex_lock(&r_Mutex); //防止readCounter 冲突
readCounter++; //只是为了++这个,上面2句下面2句
pthread_mutex_unlock(&w_Mutex); ///写解锁
pthread_mutex_unlock(&r_Mutex); ///读解锁
//先上锁一遍,再解锁??记得有个try_lock!!!???
}
//什么意思都是先加锁,再解锁。。。
void G_Lock::unrLock()
{
pthread_mutex_lock(&r_Mutex); ///读加锁
readCounter--;
if(0 == readCounter)
{
//pthread_cond_t condReadCounter;这样定义的,这也叫信号。。。这个机制还不清楚,一般都用封装好的c++类。。
pthread_cond_signal(&condReadCounter); //如果readCounter为0 , 表示已经没有读了,可以写
}
pthread_mutex_unlock(&r_Mutex); ///读解锁
}
//又是先加锁再解锁。。。
void G_Lock::wLock()
{
pthread_mutex_lock(&w_Mutex); ///写加锁
pthread_mutex_lock(&r_Mutex); ///读加锁
if(0 == readCounter) ///防止readCounter = 0而且没有调用过rLock()和unrLock()
{
pthread_mutex_unlock(&r_Mutex); ///读解锁
return ;
}
//这是对应上面的那个signal吗?
pthread_cond_wait(&condReadCounter , &r_Mutex); //等待readCounter = 0 , 等待期间r_Mutex被解锁,有信号再加锁
pthread_mutex_unlock(&r_Mutex); ///读解锁
}
//这个直接解锁,终于明白了
void G_Lock::unwLock()
{
pthread_mutex_unlock(&w_Mutex); //写解锁
}
///
/// @file def.h
/// @brief
/// @author guozhiming
/// @date 2007-04-11
///
#ifndef __DEF__
#define __DEF__
#include <iostream>
#include <errno.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <deque> //哦。有标准的queue,竟然还自己写个。
#include <signal.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <map> //标准c++
using namespace std;
typedef unsigned long ULONG;
/// @brief 为了服务器接收到client的信息把数据和client的套接字连接到一起
struct G_DataSocket
{
int nSocket;
void *pStr;
};
#endif
///
/// @file ListenThread.h
/// @brief 服务器监听线程
/// @author guozhiming
/// @date 2007-05-16
///
#ifndef __G_LISTENTHREAD__
#define __G_LISTENTHREAD__
#include "Thread.h"
#include "Socket.h"
#include "ThreadPool.h"
class G_ThreadPool; //线程池。。
class G_ListenThread : public G_Thread //还有个基类
{
public:
/// @brief 构造函数
G_ListenThread(G_ThreadPool *pool);
/// @brief 析构函数
virtual ~G_ListenThread();
/// @brief
void Run(); //哦。都是一个run,和qt的线程模式一样。
/// @brief 服务器帮定端口
///
/// @param nPort 帮定端口
///
/// @return true表示成功 , false表示失败
bool Bind(unsigned int nPort);
private:
///套接口操作的对象
G_Socket *g_socket;
G_ThreadPool *g_threadPool;
};
#endif
#include "ListenThread.h"
#include "Log.h"
G_ListenThread::G_ListenThread(G_ThreadPool *pool) : g_threadPool(pool)
{
g_socket = new G_Socket();
}
G_ListenThread::~G_ListenThread()
{
if(g_socket)
{
delete g_socket;
g_socket = NULL;
}
}
void G_ListenThread::Run()
{
pause();//看不懂,暂停,,什么时候开始。?有信号时,会中断此函数。什么信号,什么时候来?
debug_output("Listen thread is starting ....\n");
int nSocket;
while(1)
{
if(g_socket->Listen(nSocket))
{
debug_output("new client is connecting ....\n");//新的连接?那socket是客户端的socket??
g_threadPool->pushSocket(nSocket); ///填加到套接口队列//这里放的是server的socket啊??
g_threadPool->continues(); ///通知线程池,运行起来,到套接口队列中取套接口
}
}
}
bool G_ListenThread::Bind(unsigned int nPort)
{
if(!g_socket->Bind(nPort))
{
debug_output("Bind port %d is faild\n" , nPort);
return false;
}
debug_output("Bind port %d is Successful\n" , nPort);
continues();
return true;
}