为了方便, 我在这里先定义一个简化的线程模型:
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