为了方便, 我在这里先定义一个简化的线程模型:
void PrintA()
{
printf("thread[%x]: aaa\n", this_thread::get_id().hash());
}
void PrintB()
{
printf("thread[%x]: bbb\n", this_thread::get_id().hash());
}
这两种操作会在后台线程去执行, 用代码表示如下:enum CommandType
{
CommandA,
CommandB
};
atomic_int8_t IsOver = 0;
concurrent_queue<CommandType> CommandQueue;
void SendCommand(CommandType cmd)
{
CommandQueue.push(cmd);
}
atomic_int8_t IsOver = 0;
concurrent_queue<CommandType> CommandQueue;
void CommandThreadProc()
{
printf("thread[%x]: start\n", this_thread::get_id().hash());
chrono::seconds time(1);
CommandType command;
while (IsOver == 0)
{
if (CommandQueue.try_pop(command))
{
switch (command)
{
case CommandA:
PrintA();
break;
case CommandB:
PrintB();
break;
}
this_thread::sleep_for(time);
}
}
printf("thread[%x]: end\n", this_thread::get_id().hash());
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("thread[%x]: start\n", this_thread::get_id().hash());
thread t(CommandThreadProc);
SendCommand(CommandA);
SendCommand(CommandB);
this_thread::sleep_for(chrono::seconds(10));
IsOver = true;
t.join();
printf("thread[%x]: end\n", this_thread::get_id().hash());
system("pause");
return 0;
}
struct Command
{
virtual void DoCommand() = 0;
};
atomic_int8_t IsOver = 0;
concurrent_queue<Command*> CommandQueue;
void SendCommand(Command* cmd)
{
CommandQueue.push(cmd);
}
void CommandThreadProc()
{
printf("thread[%x]: start\n", this_thread::get_id().hash());
chrono::seconds time(1);
Command* command = nullptr;
while (IsOver == 0)
{
if (CommandQueue.try_pop(command))
{
command->DoCommand();
delete command;
command = nullptr;
this_thread::sleep_for(time);
}
}
printf("thread[%x]: end\n", this_thread::get_id().hash());
}
这样定义后只需要派生抽象Command就好, 增加新的操作后台线程的代码无需变动:struct CommandA : public Command
{
virtual void DoCommand() override
{
PrintA();
printf("\t%s\n", __FUNCTION__);
}
};
struct CommandB : public Command
{
virtual void DoCommand() override
{
PrintB();
printf("\t%s\n", __FUNCTION__);
}
};
/****************main****************/
SendCommand(new CommandA());
SendCommand(new CommandB());
/************************************/struct FunctionCommand : public Command
{
function<void()> fun;
FunctionCommand(function<void()> f) : fun(f) {}
virtual void DoCommand() override
{
fun();
printf("\t%s\n", __FUNCTION__);
}
};
/****************main****************/
SendCommand(new FunctionCommand(PrintA));
SendCommand(new FunctionCommand(PrintB));
/************************************/#define SEND_COMMAND(TypeName, Code) { struct TypeName##Command : public Command { virtual void DoCommand() override { Code; printf("\t%s\n", __FUNCTION__); } }; SendCommand(new TypeName##Command()); }
/****************main****************/
SEND_COMMAND(Print,
{
PrintA();
});
SEND_COMMAND(Print,
{
PrintB();
});
SEND_COMMAND(Print,
{
PrintB();
PrintA();
});
/************************************/可以看到宏参数可以是多行的, 所以一段代码可以当成宏的一个参数传入, 然后封装成对象, 真是让人想不到的办法!int _tmain(int argc, _TCHAR* argv[])
{
printf("thread[%x]: start\n", this_thread::get_id().hash());
thread t(CommandThreadProc);
SendCommand(new CommandA());
SendCommand(new CommandB());
SendCommand(new FunctionCommand(PrintA));
SendCommand(new FunctionCommand(PrintB));
SEND_COMMAND(Print,
{
PrintA();
});
SEND_COMMAND(Print,
{
PrintB();
});
SEND_COMMAND(Print,
{
PrintB();
PrintA();
});
this_thread::sleep_for(chrono::seconds(10));
IsOver = true;
t.join();
printf("thread[%x]: end\n", this_thread::get_id().hash());
system("pause");
return 0;
}
原文:http://blog.csdn.net/xoyojank/article/details/20010635