Cxx11使用bind绑定类的普通成员函数
类的定义如下:
class
pg_stask_bizmsg
{
public:
pg_stask_bizmsg();
virtual ~pg_stask_bizmsg();
protected:
//任务初始化
virtual
void
on_init();
//任务回收
virtual
void
on_finalize();
//任务运行逻辑
virtual
void
on_execute();
//任务错误处理
virtual
void
on_error();
public:
void
thread_func_point(tbizremindconfig& conf);
void
thread_func_cycle(tbizremindconfig& conf);
private:
map<std::thread::id, tbizremindconfig> m_conf;
};
需要在on_execute()函数中开启其他线程来执行任务
//任务运行逻辑
void
pg_stask_bizmsg::on_execute()
{
if (conf.i_tr_exec_mode == 1)
{
std::thread
t(std::bind(&pg_stask_bizmsg::thread_func_cycle, this, conf));
m_conf.insert(make_pair(t.get_id(), conf));
t.detach();
}
else
if (conf.i_tr_exec_mode == 2)
{
std::thread
t(std::bind(&pg_stask_bizmsg::thread_func_point, this, conf));
m_conf.insert(make_pair(t.get_id(), conf));
t.detach();
}
else
{
LOGDEBUG("");
}
}
使用要点:
1、在使用bind函数将类的普通成员函数绑定为线程执行函数时,需要在绑定时第一个参数专递this指针;
2、cxx11提供了线程等待函数,如果线程执行函数需要不停止的执行任务,建议使用std::this_thread::sleep_for(std::chrono::seconds(1));
#include "skynet_log.h"
#include "skynet_timer.h"
#include "skynet.h"
#include "skynet_socket.h"
#include <string.h>
#include <time.h>
FILE *
skynet_log_open(struct skynet_context * ctx, uint32_t handle) {
const char * logpath = skynet_getenv("logpath");
if (logpath == NULL)
return NULL;
size_t sz = strlen(logpath);
char tmp[sz + 16];
sprintf(tmp, "%s/%08x.log", logpath, handle);
FILE *f = fopen(tmp, "ab");
if (f) {
uint32_t starttime = skynet_starttime();
uint64_t currenttime = skynet_now();
time_t ti = starttime + currenttime/100;
skynet_error(ctx, "Open log file %s", tmp);
fprintf(f, "open time: %u %s", (uint32_t)currenttime, ctime(&ti));
fflush(f);
} else {
skynet_error(ctx, "Open log file %s fail", tmp);
}
return f;
}
void
skynet_log_close(struct skynet_context * ctx, FILE *f, uint32_t handle) {
skynet_error(ctx, "Close log file :%08x", handle);
fprintf(f, "close time: %u\n", (uint32_t)skynet_now());
fclose(f);
}
static void
log_blob(FILE *f, void * buffer, size_t sz) {
size_t i;
uint8_t * buf = buffer;
for (i=0;i!=sz;i++) {
fprintf(f, "%02x", buf[i]);
}
}
static void
log_socket(FILE * f, struct skynet_socket_message * message, size_t sz) {
fprintf(f, "[socket] %d %d %d ", message->type, message->id, message->ud);
if (message->buffer == NULL) {
const char *buffer = (const char *)(message + 1);
sz -= sizeof(*message);
const char * eol = memchr(buffer, '\0', sz);
if (eol) {
sz = eol - buffer;
}
fprintf(f, "[%*s]", (int)sz, (const char *)buffer);
} else {
sz = message->ud;
log_blob(f, message->buffer, sz);
}
fprintf(f, "\n");
fflush(f);
}
void
skynet_log_output(FILE *f, uint32_t source, int type, int session, void * buffer, size_t sz) {
if (type == PTYPE_SOCKET) {
log_socket(f, buffer, sz);
} else {
uint32_t ti = (uint32_t)skynet_now();
fprintf(f, ":%08x %d %d %u ", source, type, session, ti);
log_blob(f, buffer, sz);
fprintf(f,"\n");
fflush(f);
}
}
void skynet_write_log(const char *szFileName, const int nFileLine, const char* szFunc,
const unsigned int nLogId, const char *szFormat, ...)
{
va_list ap;
memset(&ap, '\0', sizeof(va_list));
char buf[2048];
memset(buf, '\0', sizeof(buf));
va_start(ap, szFormat);
vsnprintf(buf, 2048, szFormat, ap);
va_end(ap);
char szLog[4096] = { 0 };
sprintf(szLog, "[%s(%d)::%s] [DEBUG] %s \n", szFileName, nFileLine, szFunc, buf);
printf("%s", szLog);
}
void print_lua_stack(lua_State *L)
{
int nIndex;
fprintf(stderr, "==========stack top==========\n");
fprintf(stderr, " idx type value\n");
for (nIndex = lua_gettop(L); nIndex > 0; --nIndex)
{
int nType = lua_type(L, nIndex);
fprintf(stderr, " %d %s %s\n", nIndex,
lua_typename(L, nType), lua_tostring(L, nIndex));
}
fprintf(stderr, "==========stack button==========\n");
}