基础类库说明

该文档描述了基础工具类。这些工具类能够快速方便的帮你完成开发, 强烈推荐你使用!

关于线程安全:

  • 所有类的静态函数都是线程安全的;

  • 除了TC_Thread开头的类是线程安全外,其他类都不是线程安全的(不能两个线程同时操作一个对象);

  • 如果只是只读,则是线程安全的;

异常类

TC_Exception

异常基类,所有的异常都直接或者间接继承与它;

构造函数中,提供了一个可以传入errno的构造函数,异常抛出时直接获取strerror(errno)的错误信息;

建议用:TC_Exception::getSystemCode() 获取错误码, windows下是GetLastError(), linux/mac下是errno, 用TC_Exception::parseError(TC_Exception::getSystemCode())获取错误信息.

帮助类

TC_Common

基础工具类,提供了一些非常基本的函数使用。

这些函数都是以静态函数提供。

包括以下几种函数:

  • Trim类函数:trim,trimLeft,trimRight;

  • 大小写转换函数:lower、upper;

  • 分隔字符串函数:sepstr (直接分隔字符串,数字等)

  • 时间相关函数:str2tm、tm2str、now2str、tm2GMTstr、now2GMTstr、now2us;

  • 字符串转换函数:tostr、strto;

  • 二进制字符串互转函数:bin2str、str2bin;

  • 替换字符串函数:replace;

  • Ip匹配函数:matchPeriod;

  • 其他常用的函数

TC_File

文件相关的操作。

这些函数都是以静态函数提供。

  • 获取文件大小:getFileSize

  • 是否是绝对路径:isAbsolute

  • 文件是否存在:isFileExist,isFileExistEx

  • 规则化目录:simplifyDirectory

  • 创建目录:makeDir、makeDirRecuresive

  • 设置文件可执行:setExecutable(windows下没有)、canExecutable

  • 删除文件:removeFile

  • 读取小文件到内存(string):load2str

  • 写内存(string)到文件:save2file

  • 获取文件可执行路径:getExePath

  • 分析文件名称:extraceFileName、extractFilePath、extractFileExt、excludeFileExt、replaceFileExt、extractUrlFilePath

  • 遍历目录:scanDir、listDirectory

  • 拷贝文件:copyFile

编解码、加密类

TC_Des

  • des的加密/解密函数;

  • 3des加密/解密函数;

  • 函数以静态形式提供,线程安全;

  • des/3des加密解密源码, 不依赖任何库

  • 网上流行的d3des.h d3des.c修改完成;

  • Key必须是null结束的字符串.

对于des加密:

  • 8位密钥,不足8位的右补0x00;

  • 多余8位,只取左8位有效;

  • 加密内容8位补齐,补齐方式为:少1位补一个0x01,少2位补两个0x02,...

  • 本身已8位对齐的,后面补八个0x08

对于3des加解密:

  • 只支持3des-ecb加密方式;

  • 24位密钥,不足24位的右补0x00;

  • 多余24位,只取左24位有效;

  • 加密内容8位补齐,补齐方式为:少1位补一个0x01,少2位补两个0x02,...

  • 本身已8位对齐的,后面补八个0x08;

#define KEY  "dRa93seg"
#define KEY3 " dRa93segdRa93seg dRa93seg"

string n = "abde";
{
    string s = n;
    cout << "des encrypt:" << s << endl;
    string v = taf::TC_Des::encrypt(KEY, s.c_str(), s.length());
    cout << "encrypt:" << TC_Common::bin2str(v) << endl;
    string s1 = TC_Des::decrypt(KEY, v.c_str(), v.length());
    cout << "des decrypt:" << s1 << endl;
}

{
    string s = n;
    cout << "encrypt:" << s << endl;
    string v = taf::TC_Des::encrypt3(KEY3, s.c_str(), s.length());
    cout << "encrypt:" << TC_Common::bin2str(v.c_str()) << endl;
    string s1 =TC_Des::decrypt3(KEY3, v.c_str(), v.length());
    cout << "decrypt:" << s1 << endl;
}

TC_Base64

标准base64的编解码函数,通过静态函数提供。

string src = “abc”;
//编码
string dest =TC_Base64::encode(src);
//解码
string src1 = TC_Base64::decode(dest);
assert(src == src1);

TC_MD5

Md5的散列算法,通过静态函数提供。

string src = “test”;
string hs = TC_MD5::md5str(src);
cout << hs << endl;

TC_Encoder

Gbk到utf8之间的相互转码函数,通过静态函数提供。

string s = "我们";
string v = TC_Encoder::gbk2utf8(s);
cout << s << ":" << v << ":" << TC_Encoder::utf82gbk(v) << endl;

该类也提供了transTo/transFrom函数用于将string的\n替换掉,或从替换的数据恢复源数据,主要用于将string记录在一行,通常用于写bin-log的地方。

TC_Pack

  • 二进制的组包解包类,通过<<、>>操作符实现;

  • 对string,采用了压缩格式:长度<255: 1个字节长度, 内容;长度>=255, 4个字节(长度), 内容;

  • 所有整形/长度值都采用字节序;

  • 非线程安全;

TC_Parsepara

  • 提供name=value&name1=value1形式的解析函数;

  • 可以和map互相转换;

  • 不是标准的cgi参数的解析(标准cgi参数解析会把空格和+互转);

  • 非线程安全;

锁类

注意:对于线程锁,TAF5.0可以直接使用c++11的锁了!这些类的存在是为了兼容TAF低版本!

TC_SemMutex

  • 进程锁, 可以跨进程加锁

  • Linux/Mac下IPC信号量锁,进程、线程间锁;

  • Windows使用的Mutex/Event实现

  • 提供了读写锁功能;

TC_LockT

  • 模板锁类,和其他具体锁配合使用。

  • 构造时候加锁,析够的时候解锁;

  • TC_TryLockT类似,用于锁尝试操作;

  • TC_EmptyMutex:空锁,不提供任何操作;

  • 其他具体锁的加解锁函数一样,保证能够和TC_LockT配合使用;

TC_SemMutex sm;
sm.init(8888);
TC_LockT<TC_SemMutex> sync(sm);

TC_ThreadMutex tm;
TC_LockT< TC_ThreadMutex > sync(tm);

TC_ThreadMutex

  • 线程锁,不可重复加锁,即同一个线程不可以重复加锁;

  • 通常不直接使用,和TC_Monitor配合使用,即TC_ThreadLock;

TC_ThreadRecMutex

  • 线程锁,可重复加锁,即同一个线程可以重复加锁;

  • 通常不直接使用,和TC_Monitor配合使用,即TC_ThreadRecLock;

TC_ThreadRWLock

  • 线程级别的读写锁, 采用c++11 mutex封装实现

TC_ThreadCond

  • 线程信号条件类,和TC_ThreadMutex、TC_ThreadRecMutex配合使用;

  • 通常不直接使用,而是使用TC_ThreadLock/TC_ThreadRecLock;

TC_Monitor

  • 线程锁监控模板类。

  • 通常线程锁,都通过该类来使用,而不是直接用TC_ThreadMutex、TC_ThreadRecMutex。

  • 该类将TC_ThreadMutex/TC_ThreadRecMutex 与TC_ThreadCond结合起来;

定义了两个线程锁的模板:

/**
 * 普通线程锁
 */
typedef TC_Monitor<TC_ThreadMutex, TC_ThreadCond> TC_ThreadLock;

/**
 * 循环锁(一个线程可以加多次锁)
 */
typedef TC_Monitor<TC_ThreadRecMutex, TC_ThreadCond> TC_ThreadRecLock;

在使用中,强烈建议使用:TC_ThreadLock、TC_ThreadRecLock;

关键成员函数说明:

  • wait:当前调用线程在锁上等待,直到事件通知;

  • timedWait:当前调用线程在锁上等待,直到超时或有事件通知;

  • notify:通知等待在该锁上某一个线程醒过来,注意调用该函数时必须已经获得锁;

  • notifyAll:通知等待在该锁上的所有线程醒过来,注意调用该函数时必须已经获得锁;

内存结构、文件映射类、数据结构类

TC_Bitmap

  • 内存bitmap,每个整数1位;

  • 可以支持多位,即几个整数多位;

  • 操作过程不加锁,如果有需要在外面调用的时候加,通常采用群锁策略;

  • 注意群锁策略应该/8,然后按照尾号分群锁

TC_Shm      g_shm;
TC_BitMap   g_bmap;
//计算4字节整型的bitmap需要多大内存
size_t iMemSize    = TC_BitMap::calcMemSize(uin32_t(-1));
//初始化共享内存
g_shm.init(iMemSize, 9999);
//创建bitmap
if (g_shm.iscreate())
{
    g_bmap.create(g_shm.getPointer(), g_shm.size());
}
else
{
    g_bmap.connect(g_shm.getPointer(), g_shm.size());
}
//获取某一个整型对应的一位,超出bitmap则返回-1
cout << "get:" << uin << "=" << g_bmap.get(uin) << endl;
//设置整型
cout << "set:" << uin << "=" << g_bmap.set(uin) << endl;
//清除整型
cout << "clear:" << uin << "=" << g_bmap.clear(uin) << endl;
//从dump到文件
int ret = g_bmap.dump2file(file);
//从文件load
int ret = g_bmap.load5file(file);

TC_Hashmap(注意, 不建议使用了!!!!)

  • 内存hashmap,不要直接使用该类,通过jmem组件来使用,具体请参见11.3

  • 该hashmap通过TC_MemMutilChunkAllocator来分配空间,支持不同大小的内存块的分配;

  • 支持内存和共享内存;

  • 对接口的所有操作都需要加锁;

  • 内部有脏数据链,支持数据缓写;

  • 当数据超过一个数据块时,则会拼接多个数据块;

  • Set时当数据块用完,自动淘汰最长时间没有访问的数据,也可以不淘汰,直接返回错误;

  • 支持dump到文件,或从文件load;

TC_HashmapCompact

  • 紧凑性hashmap,使用方式同TC_Hashmap,但是64位系统下更节约额外的管理空间;

  • 最大每个value的长度只能是64K(两个字节), 所以需要需要保存更大的数据, 建议使用TC_Hashmap

TC_RBTree

  • 内存rbtree,不要直接使用该类,通过jmem组件来使用,具体请参见11.4

  • 该红黑树通过TC_MemMutilChunkAllocator来分配空间,支持不同大小的内存块的分配;

  • 分配器分配的是内存索引,减少自身消耗的空间(尤其是64位OS下面);

  • 支持内存和共享内存;

  • 对接口的所有操作都需要加锁;

  • 内部有脏数据链,支持数据缓写;

  • 当数据超过一个数据块时,则会拼接多个数据块;

  • Set时当数据块用完,自动淘汰最长时间没有访问的数据,也可以不淘汰,直接返回错误;

  • 支持dump到文件,或从文件load;

TC_MemQueue

内存循环队列,建议不要直接使用该类,通过jmem组件来使用,具体参见11.2

TC_Shm shm;
shm.init(8000, 1024);
TC_SemMutex  semLock;
semLock.init(8000);

TC_MemQueue memQueue;
//创建队列
if(shm.iscreate())
{
    memQueue.create(shm.getPointer(), 1024);
}
else
{
    memQueue.connect(shm.getPointer());
}

string sTest = “abc”;
//放入到队列尾部
memQueue.push(sTest);
//弹出数据
memQueue.pop(sTest);

TC_MemVector

  • 基于内存的随机访问数据快模板类;

  • 每个块大小相同;

  • 模板对象只支持简单的数据类型,即类型支持bit-copy语义;

struct tagTest
{
	char i;
	int n;
	float a[10];
} __attribute__((packed));
//__attribute__((packed))表示采用紧缩内存结构

TC_MemVector<tagTest> vt;
//计算总计内存空间
size_t is = TC_MemVector<tagTest>::calcMemSize(10);
char *buffer = new char[is];
//创建到对象
vt.create(buffer, is);
//链接到对象, vt.connect(buffer);
//获取对象0的对象
vt[0].i = ‘c’;
vt[0].n = 10;
delete []buffer;

TC_Mmap

  • 文件内存映射类

  • linux/mac下使用mmap实现

  • windows下使用文件映射内存实现

  • 封装了mmap的操作;

TC_Mmap mmap;
//映射到文件,1024个字节
mmap.mmap("mmap.dat", 1024);
string s = “abc”;
//向文件copy数据,和内存操作完全一致;
memcpy(mmap.getPointer(), s.c_str(), s.length());

内存分配

TC_MemChunk

  • 相同大小内存块类;

  • 支持内存和共享内存;

  • 每块内存至少4个字节;

TC_MemChunkAllocator

  • 内存块分配器,提供分配和释放的功能;

  • 只能分配相同大小的内存块;

  • 每个内存块用TC_MemChunk来管理;

TC_MemMultiChunkAllocator

  • 内存块分配器,提供分配和释放的功能;

  • 支持分配不同大小的内存块;

  • 内部每种块用TC_MemChunkAllocator来分配;

  • 每种大小不同块的个数是相同的;

内存块分配的策略如下:

  • 确定需要分配多大内存,假设需要分配A字节的内存;

  • 分配大小大于>=A的内存块,优先分配大小最接近的;

  • 如果都没有合适内存块,则分配大小<A的内存块,优先分配大小最接近的;

  • 如果仍然没有合适内存块,则返回NULL;

char *buffer = new char[50240];
//定义分配器对象
TC_MemMultiChunkAllocator alloc;
//初始化,10:最小块大小,100:最大块大小,1.2:增长因子,表示块之间大小的增长比值		
alloc.create(buffer, 50240, 10, 100, 1.2);
vector<void*> v;
//定义需要分配的大小
size_t n = 10;
while(true)
{
    size_t iAllocSize;
    //分配空间,iAllocSize:真正分配的块大小
    void *p = alloc.allocate(n, iAllocSize);
    if(!p)
    {
        break;
    }
    v.push_back(p);
    n += 2;
}
//释放空间
for(size_t i = 0; i < v.size(); i++)
{
    alloc.deallocate(v[i]);
}
delete []buffer;

TC_Shm

  • 共享内存管理类;

  • 提供分配共享内存、连接共享内存、删除共享内存的功能;

  • Linux/mac下用IPC的shm实现

  • Windows下使用文件映射内存实现

TC_Shm      g_shm;
size_t iMemSize = 10240;
g_shm.init(iMemSize, 9999);
if (g_shm.iscreate())
{
    //共享内存是创建的
        ;
}
else
{
    //共享内存是链接上的
;
}
//删除共享内存,类似ipcrm -M
g_shm.del();

TC_ThreadQueue

  • 基于内存、STL容器的线程安全队列;

  • 采用TC_ThreadLock加解锁;

//定义队列
TC_ThreadQueue<string> _queue;
//循环获取数据
while(true)
{
	//没有数据则等待10000ms
    if(_queue.pop_front(s, 10000))
    {
        cout << s << endl;
    }
    sleep(1);
}
while(true)
{
	//放入数据
    _queue.push_back(s);
    sleep(1);
}
//当程序退出时,如果线程仍然等待在pop_front上,则线程锁析够的时会有问题,此时需要用notifyT通知在pop_front上等待的线程醒过来
_queue.notifyT();

TC_TimeoutQueue

  • 基于内存、STL容器的线程安全超时队列;

  • 在如下场景中使用:

    • 需要当成map, 可以快速读写key-value数据;

    • 需要能够设置超时时间, 到点淘汰数据;

主要用于: 超时队列使用, 框架中也大量使用这个类

数据库类

TC_Mysql

  • 提供mysql的操作类;

  • 非线程安全,通常一个线程一个TC_Mysql对象;

  • 对于insert/update可以有更好的函数封装,保证SQL注入;

  • TC_Mysql::DB_INT表示组装sql语句时,不加””和转义;

  • TC_Mysql::DB_STR表示组装sql语句时,加””并转义;

TC_Mysql mysql;
//初始化mysql,init时不链接,请求时自动建立链接;
//数据库可以为空;
//端口默认为3306
mysql.init("10.1.36.39", "pc", "pc@sn", "db_dmqq_system");
//获取链接的字符集
cout << mysql.getVariables("character_set_client") << endl;
//获取数据
TC_Mysql::MysqlData data;
data = mysql.queryRecord("select * from t_app_users");
for(size_t i = 0; i < data.size(); i++)
{
    //如果不存在ID字段,则抛出异常
    cout << data[i]["ID"] << endl;
}

//插入数据,指定数据的类型:数值 或 字符串,对于字符串会自动转义
map<string, pair<TC_Mysql::FT, string> > m;
m["ID"]     = make_pair(TC_Mysql::DB_INT, "2334");
m["USERID"] = make_pair(TC_Mysql::DB_STR, "abcttt");
m["APP"]    = make_pair(TC_Mysql::DB_STR, "abcapbbp");
m["LASTTIME"]    = make_pair(TC_Mysql::DB_INT, "now()");

//   mysql.insertRecord("t_user_logs", m);
mysql.replaceRecord("t_user_logs", m);

网络类

TC_Socket

  • 提供socket的操作类;

  • 支持tcp/udp socket;

  • 支持本地域套接字;

//获取本地的所有ip地址
vector<string> v = TC_Socket::getLocalHosts();
cout << TC_Common::tostr(v.begin(), v.end()) << endl;

TC_Epoller

提供网络epoll的操作类。

TC_Transceiver

提供网络连接的操作类, 具体使用请参考头文件。

TC_CoroutineScheduler

协程调度器.

TC_CoroutineQueue

协程调度队列.

用于跨线程的协程的数据交互, 队列没有数据时, 协程会阻塞在epoller上, 当有网络事件或者其他协程调度时会被唤醒处理其他事件!

TC_ClientSocket

提供客户端同步请求的socket类,用于发送数据包,支持tcp/udp,支持大句柄

  • 在TC_Socket基础上实现;

  • 多线程使用的时候,不用多线程同时send/recv,小心串包;

  • TC_TCPClient:tcp的客户端类,socket句柄自动重连;

  • TC_UDPClient:udp的客户端类;

  • TC_TCPClient/TC_UDPClient的发送或接收数据的返回值请参见TC_ClientSocket::EM_等枚举值;

  • 初始化时指定:ip,port,超时时间(毫秒),注意对连接超时也处理了;

  • 支持本地套接字,如果端口port是0表示是本地套接字,此时ip表示本地套接字的文件路径;

TC_TCPClient

  • 多线程使用的时候,不用多线程同时send/recv,小心串包;

  • send:发送数据

  • recv:接收数据

  • recvLine:接收一行,即直到\r\n位置;

  • recvAll:接收所有数据,直到服务器关闭链接;

  • recvLength:接收指定长度的数据;

  • sendRecv:发送并接收数据;

  • sendRecvLine:发送并接收一行数据;

  • sendRecvAll:发送并接收所有数据(直到服务器关闭链接);

socket被关闭,会自动重新链接;

TC_UDPClient

  • 多线程使用的时候,不用多线程同时send/recv,小心串包;

  • send:发送数据

  • recv:接收数据

  • recv:接收数据并返回远程的ip和端口

  • sendRecv:发送并接收数据;

  • sendRecv:发送并接收数据,同时返回远程ip和端口;

线程类

TC_Thread

线程基类,所有自定义线程继承于该类,同时实现run接口即可。可以通过TC_ThreadContorl管理线程。

线程最大的问题就是如何正确的退出。通常一个线程在运行过程中,会做一些工作(比如从队列中获取数据执行计算),如果队列为空,就休息一会儿再执行,这里如果采用sleep来休息,则退出过程中,恰好在sleep,则必须等这时间之后才能退出。下面例子给出了如何正常退出一个线程的思路:

class MyThread : public TC_Thread, public TC_ThreadLock
{
public:
    MyThread()
    {
        bTerminate = false;
    }
    /**
     * 结束线程
     */
    void terminate()
    {
		//先将退出标识设置为true
        bTerminate = true;
		
        {
			//加锁并通知线程醒过来
            TC_ThreadLock::Lock sync(*this);
            notifyAll();
        }
    }

    void doSomething()
    {
        cout << "doSomething" << endl;
    }
    /**
     * 运行
     */
protected:
    virtual void run() 
    {
        while(!bTerminate)
        {
             //TODO: your business
            doSomething();

			//做完工作以后,等待一下,注意在锁上等待,通知线程醒来的时候也是在锁上通知
            {
                TC_ThreadLock::Lock sync(*this);
                timedWait(1000);
            }
        }
    }

protected:
    bool bTerminate;
};

int main(int argc, char *argv[])
{
    try
    {
        MyThread mt;
        mt.start();

        sleep(5);
		
		//通知线程结束,并等待线程完全退出
        mt.terminate();
        mt.getThreadControl().join();
    }
    catch(exception &ex)
    {
        cout << ex.what() << endl;
    }

    return 0;
}

说明:关键的思路就是采用线程锁来完成通知,保证线程正确、安全、及时的退出。

TC_ThreadPool

  • 线程池类;

  • 需要和std::bind配合使用;

  • 方便的多线程执行一个具体操作;

日志类

TC_Logger

  • 日志模板类;

  • 支持同步写、异步写;

  • 线程安全的;

  • 定义了TC_DayLogger, TC_RollLogger,通常直接使用这两个类即可;

CGI类

TC_Cgi

  • CGI解析类;

  • 支持标准的HTTP解析;

  • 支持Cookies;

  • 支持多个文件的上传;

TC_Http

  • Http协议解析类;

  • 包括TC_HttpRequest、TC_HttpResponse两个类;

  • 支持GET和POST,其他HTTP方法不支持;

  • 通过TC_HttpRequest::checkRequest判断http请求是否收完;

  • 与TC_ClientSocket配合,支持同步发送http请求,且支持http的chunk编码;

  • 发送http请求时,非线程安全;

 //定期http request对象
TC_HttpRequest stHttpReq;
stHttpReq.setCacheControl("no-cache");
//设置agent
stHttpReq.setUserAgent("TestAgent");
//设置请求地址和方式(GET方式请求)
stHttpReq.setRequest("http://www.qq.com", TC_HttpRequest::REQUEST_GET);
TC_HttpResponse stHttpRep;
//发送请求,并等待完整的HTTP响应,超时时间为10s
int iRet = stHttpReq.doRequest(stHttpRep, 10000);
if(iRet != 0)
{
    cout << iRet << endl;
}
//HTTP响应包的内容
cout << stHttpRep.getContent();

TC_HttpAsync

  • Http协议异步请求类

  • 支持ssl

TC_UUIDGenerator

  • 单例

  • 生成唯一的UUID

命令解析、配置文件类

TC_Config

  • 配置文件解析类

  • 支持从string中解析配置文件;

  • 支持生成配置文件

  • 解析出错抛出异常;

  • 采用[]获取配置,如果无配置则抛出异常;

  • 采用get获取配置,不存在则返回空;

  • 读取配置文件是线程安全的,insert域等函数非线程安全;

例如:

TC_Config conf;
//解析配置文件
conf.parseFile("./config.conf");
//输出配置文件格式
cout << conf.tostr() << endl;
//配置文件读入到内存
string s = TC_File::load2str("./config.conf");
//解析字符串
conf.parseString(s);
//读取root域下root字段,不存在则抛出异常
cout << conf["/root<root>"] << endl;
//读取root域下root字段,不存在则返回abc
cout << conf.get("/root<root>", “abc”) << endl;
//root/insert下插入insert子域,false:表示root/insert不存在时不创建
conf.insertDomain("/root/insert", "insert", false);		
map<string, string> m;
m["abc"] = "def";
m["ttt"] = "yyy";
//root/insert/insert下创建参数值对,false 表示/root/insert/insert不存在,则不创建
conf.insertDomainParam("/root/insert/insert", m, false);
//root/insert/insert下创建参数值对,true:表示自动创建
conf.insertDomainParam("/root/insert/insert", m, true);
cout << conf.tostr() << endl;

TC_Option

  • 命令解析类;

  • 通常用于解析命令行参数;

  • 只支持双—的参数形式

分析main的输入参数,支持以下形式的参数:

./main.exe --name=value --param1 param2 param3

 TC_Option op;
//解析命令行
op.decode(argc, argv);
//获取成对的参数,即获取 - - 表示的所有参数对
map<string, string> mp = op.getMulti();
//表示非 – 的参数:即 param2, param3
vector<string> d = op.getSingle();

如果value,param有空格或者--,用引号括起来就可以了。

智能指针类

TC_AutoPtr

  • 智能指针模板类;

  • 通过它定义智能指针;

  • 该智能指针通过引用计数实现,可以放在容器中传递;

  • 使用方式请参见:TC_HandleBase

  • 其实可以用c++11中shared_ptr代替!!

TC_HandleBase

  • 智能指针基类;

  • 采用TC_AutoPtr模板化的对象,必须都继承于该类;

  • 内部采用引用计数std::atomic实现;

  • 对象可以放在容器中;

例如:

class TestAuto : public TC_HandleBase
{
    
};

Typedef TC_AutoPtr<TestAuto> TestAutoPtr;

其他类

TC_GZip

  • Gzip压缩解压类, 需要连接zlib

  • 仅仅支持linux/mac

TC_TimeProvider

  • 时间获取类,获取毫秒/秒

  • 不直接使用时间获取函数得到

  • 背后有一个常驻线程, 通过计算cpu的频率来获取, 减少时间函数调用的用户内核态切换

  • 建议需要获取时间的函数都通过这个类来得到

TC_Singleton(单例)

TC_Json

  • Json解析类, 通常不直接使用

  • Jce结构体都会生成json的对应函数

  • 必要的时候可以使用

TC_Timer

  • 定时器类

  • 可以设置定事情, 并执行回调

  • 可以设置回调的线程数

Last updated