什么叫事务线程

举个例子:
我们写一个IM客户端的登录子线程,则该子线程会有这么几个事务要处理
No.1 TCP Socket物理连接
No.2 逻辑登录
No.3 好友在线查询
No.4 状态更新
我们通常的代码写法是
  1. void ThreadLogin()
  2. {
  3. try
  4. {
  5. if(fail(物理连接))
  6. throw;
  7. if(fail(登录))
  8. throw;
  9. if(fail(查询好友))
  10. throw;
  11. if(fail(更新))
  12. throw;
  13. }
  14. catch(exception)
  15. {
  16. }
  17. }

串行的逻辑用串行的代码写,不太好看,况且中途如果主线程发出取消指令,还不好处理。

这里扩展的thread类,就是来解决这个问题的,他会提供给程序员一种事件处理的模式
  1. class threadLogin
  2. {
  3. void onEventConnect()
  4. {
  5. 物理连接
  6. }
  7. void onEventLogin()
  8. {
  9. 登录
  10. }
  11. void onEventQuery()
  12. {
  13. 查询
  14. }
  15. void onEventUpdate()
  16. {
  17. 更新
  18. }
  19. }
源码如下
  1. // thread.hpp : controlled_module_ex类的扩展
  2. // 增强线程事务处理能力
  3. #pragma once
  4. #include "controlled_module_ex.hpp"
  5. class thread: public controlled_module_ex
  6. {
  7. protected:
  8. static const int NONE = -1;
  9. static const int WAITING =-2;
  10. static const int DONE =-3;
  11. static const int FAILED =-4;
  12. protected:
  13. struct process
  14. {
  15. int level;
  16. int status;
  17. int sequence;
  18. int trycount;
  19. int tryindex;
  20. std::string lasterror;
  21. double timeout;
  22. bool bTimeout;
  23. };
  24. process m_process;
  25. controlled_timer m_timer_process;
  26. int m_process_begin,m_process_end;
  27. double m_timeout_default;
  28. public:
  29. void startprocess(int process_begin,int process_end,double timeout_default=1.0,int cycle=1000)
  30. {
  31. m_process_begin = process_begin;
  32. m_process_end = process_end;
  33. m_timeout_default = timeout_default;
  34. m_process.level = m_process_begin;
  35. m_process.tryindex = 0;
  36. this->postmessage(BM_RING_PROCESS);
  37. m_timer_process.starttimer(cycle,this);
  38. }
  39. void tryagain()
  40. {
  41. if(this->m_process.level==thread::NONE)
  42. return;
  43. this->m_process.tryindex++;
  44. if(this->m_process.trycount>0 && this->m_process.tryindex>=this->m_process.trycount)
  45. {
  46. this->fail();
  47. }
  48. else
  49. this->postmessage(BM_RING_PROCESS);
  50. }
  51. void next()
  52. {
  53. if(this->m_process.level==thread::NONE)
  54. return;
  55. if(this->m_process.level>=this->m_process_end)
  56. {
  57. this->m_timer_process.stoptimer();
  58. this->postmessage(BM_RING_PROCESSEND);
  59. }
  60. else
  61. {
  62. this->m_process.tryindex = 0;
  63. this->m_process.level++;
  64. this->m_process.bTimeout = false;
  65. this->postmessage(BM_RING_PROCESS);
  66. }
  67. }
  68. void fail()
  69. {
  70. m_process.level = thread::NONE;
  71. this->m_timer_process.stoptimer();
  72. this->postmessage(BM_RING_PROCESSFAIL);
  73. }
  74. virtual void on_safestart()
  75. {
  76. m_process.level = thread::NONE;
  77. m_process.status = thread::NONE;
  78. m_process_begin = m_process_end = thread::NONE;
  79. controlled_module_ex::on_safestart();
  80. }
  81. virtual void on_safestop()
  82. {
  83. m_timer_process.stoptimer();
  84. controlled_module_ex::on_safestop();
  85. }
  86. virtual void message(const _command & cmd)
  87. {
  88. controlled_module_ex::message(cmd);
  89. if(cmd.nCmd==BM_RING_PROCESS)
  90. {
  91. this->on_process();
  92. }
  93. if(cmd.nCmd==BM_RING_PROCESSEND)
  94. {
  95. this->m_process.level = thread::NONE;
  96. this->on_process_end();
  97. }
  98. if(cmd.nCmd==BM_RING_PROCESSFAIL)
  99. {
  100. this->m_process.level = thread::NONE;
  101. this->on_process_fail();
  102. }
  103. }
  104. virtual void on_timer(const controlled_timer * p)
  105. {
  106. if(p==this->m_timer_process)
  107. {
  108. if(this->m_process.level!=thread::NONE)
  109. {
  110. if(this->m_process.level>=this->m_process_begin && this->m_process.level<=this->m_process_end)
  111. {
  112. if(this->m_process.status==thread::NONE)
  113. {
  114. this->m_process.level = this->m_process_begin;
  115. m_process.tryindex = 0;
  116. on_process();
  117. }
  118. else if(this->m_process.status==thread::WAITING)
  119. {
  120. if(this->m_process.timeout>0)
  121. {
  122. time_t cur;
  123. time(&cur);
  124. if(difftime(cur,(time_t)this->m_process.sequence)>this->m_process.timeout)
  125. {
  126. this->m_process.bTimeout = true;
  127. this->tryagain();
  128. }
  129. }
  130. }
  131. else if(this->m_process.status==thread::FAILED)
  132. {
  133. this->tryagain();
  134. }
  135. else if(this->m_process.status==thread::DONE)
  136. {
  137. this->m_process.level++;
  138. m_process.tryindex = 0;
  139. this->on_process();
  140. }
  141. }
  142. }
  143. }
  144. }
  145. virtual void on_process()
  146. {
  147. time((time_t*)&m_process.sequence);
  148. m_process.timeout = m_timeout_default;
  149. m_process.status = thread::WAITING;
  150. m_process.trycount = -1;
  151. }
  152. virtual void on_process_end(){}
  153. virtual void on_process_fail(){}
  154. int get_sequence(){return m_process.sequence;}
  155. void put_timeout(double v){m_process.timeout = v;}
  156. void put_trycount(int v){m_process.trycount = v;}
  157. int get_level(){return m_process.level;}
  158. void put_level(int v){m_process.level=v;}
  159. std::string get_lasterror(){return m_process.lasterror;}
  160. void put_lasterror(std::string v){m_process.lasterror=v;}
  161. __declspec(property(put=put_trycount)) int trycount;
  162. __declspec(property(put=put_timeout)) double timeout;
  163. __declspec(property(get=get_level,put=put_level)) int level;
  164. __declspec(property(get=get_sequence)) int sequence;
  165. __declspec(property(get=get_lasterror,put=put_lasterror)) std::string lasterror;
  166. };

虚拟函数thread::on_process()处理各种事务事件

虚拟函数thread::on_process_end()是所有事务处理完毕事件
虚拟函数thread::on_process_fail()是事务处理出现错误,这时所有事务被取消,线程终止
这里给一个简单的范例,
总共线程要完成3件事务,其中第二个事务要求用户确认是否继续
 
  1. #define PROCESS_1   1
  2. #define PROCESS_2   2
  3. #define PROCESS_3   3
  4. class thdex: public thread
  5. {
  6. public:
  7. virtual void on_process()
  8. {
  9. thread::on_process();
  10. if(this->level==PROCESS_1)
  11. {
  12. cout << "work on process 1..." << endl;
  13. Sleep(100);
  14. cout << "process 1 done." << endl;
  15. this->next();
  16. }
  17. else if(this->level==PROCESS_2)
  18. {
  19. cout << "work on process 2..." << endl;
  20. this->timeout = -1;
  21. if(IDNO==::MessageBox(0,"are your want continue?","ask",MB_ICONQUESTION|MB_YESNO))
  22. {
  23. this->lasterror = "canceled by user";
  24. this->fail();
  25. }
  26. else
  27. {
  28. Sleep(100);
  29. cout << "process 2 done." << endl;
  30. this->next();
  31. }
  32. }
  33. else if(this->level==PROCESS_3)
  34. {
  35. cout << "work on process 3..." << endl;
  36. Sleep(100);
  37. cout << "process 3 done." << endl;
  38. this->next();
  39. }
  40. }
  41. virtual void on_process_fail()
  42. {
  43. cout << this->lasterror << endl;
  44. }
  45. virtual void on_process_end()
  46. {
  47. cout << "all process done." << endl;
  48. }
  49. };
  50. int _tmain(int argc, _TCHAR* argv[])
  51. {
  52. thdex t;
  53. t.safestart();
  54. t.startprocess(PROCESS_1,PROCESS_3);
  55. char buf[10];
  56. gets_s(buf,sizeof buf);
  57. t.safestop();
  58. return 0;
  59. }

BOOST 线程完全攻略 - 扩展 - 事务线程的更多相关文章

  1. BOOST 线程完全攻略 - 扩展 - 线程消息通讯

      // controlled_module_ex.hpp : controlled_module类的扩展 // 增强线程之间消息通讯 // 增加线程安全启动和安全关闭功能 // 增加定时器功能 #p ...

  2. BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类

    本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...

  3. BOOST 线程完全攻略 - 基础篇

    http://blog.csdn.net/iamnieo/article/details/2908621 2008-09-10 12:48 9202人阅读 评论(3) 收藏 举报 thread多线程l ...

  4. BOOST 线程完全攻略

    1 创建线程 首先看看boost::thread的构造函数吧,boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象: (2)explicit thre ...

  5. 【C/C++】BOOST 线程完全攻略 - 基础篇

    C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个 ...

  6. BOOST 线程完全攻略 - 结束语

    modulethread扩展多线程破解通讯 全文介绍了3个boost::thread的扩展类,希望能给大家书写多线程代码带来便捷. thread -> controlled_module_ex ...

  7. Java视频扩展知识 线程池的了解

     Java视频扩展知识   线程池的了解 1.简单介绍: Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的 ...

  8. Chrome插件(扩展)开发全攻略

    [干货]Chrome插件(扩展)开发全攻略:https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html

  9. 线程本地变更,即ThreadLocal-->Spring事务管理

    我们知道Spring通过各种模板类降低了开发者使用各种数据持久技术的难度.这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突.我们使用模板类访问底层数据,根据持久化技术 ...

随机推荐

  1. asp.net 正则表达式

    在平时的开发中常常用到替换法:  普通的字符串替换可以使用string.replace(string,string),但是比较难解决HTML文本的替换. 经我几番查找,终也找出解决办法:正则匹配替换. ...

  2. Java数据输入

    以下是数据输入实例: //以下是数据输入实例 import java.util.Scanner;//导入java.util.Scanner,Scanner首字母大写 public class Test ...

  3. QTP描述性编程中往WebEdit控件输入文字问题

    在网上查找到许多相关的描述性编程的案例,自己就想动手一试,于是在专家视图中输入如下代码: systemUtil.Run "http://www.baidu.com" wait(15 ...

  4. silverlight+wcf 项目 silverlight获得web程序的参数

    silverlight 可以通过属性InitParams 获得参数,如果参数是动态的需要web程序传递的,具体操作如下: web程序后台:AppID,USERID需要的参数 this.frmRepor ...

  5. 洛谷 P1830 轰炸Ⅲ

    P1830 轰炸Ⅲ 题目提供者wanglichao1121 标签模拟矩阵洛谷原创 难度普及/提高- 题目背景 一个大小为N*M的城市遭到了X次轰炸,每次都炸了一个每条边都与边界平行的矩形. 题目描述 ...

  6. 【0】Laravel 5.1 简介

    1.简介 Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以 ...

  7. redis数据结构与主要命令

    redis的数据类型有:string.hashes.lists.sets,sorted sets 1.string类型: set.get添加键值对获得键值对.如果多次赋值会覆盖掉原来的value se ...

  8. android图像模糊技术

    今天我们来更深入了解一下Android开发上的模糊技术.我读过几篇有关的文章,也在StackOverFlow上看过一些相关教程的帖子,所以我想在这里总结一下学到的东西. 为什么学习这个模糊技术? 现在 ...

  9. hdu 5305Friends

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5305 Problem Description There are n people and m pai ...

  10. Realm

    还在为数据库不能获取最新数据而犯愁?信我,你只是需要一个活着的数据库——Realm 写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里 ...