使用boost线程定时器作为后台线程来切换主循环程序状态方法总结

 

  1:简单了解boost定时器

复制代码
#include "stdafx.h"
#include <string>
#include <boost\thread.hpp>
#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
using namespace boost;
int exit1 = 1;
void printing(int& len)
{
    this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
    len++;
    exit1 = 0;
}
int _tmain(int argc, _TCHAR* argv[])
{    
    //绑定简单函数
    int len = 2;
    thread(printing, len);//默认构造函数都是复制值传递,如果要使用引用传递请使用
    //thread(printing, ref(len));
    while (exit1);//线程中定时后改变系统阻塞的状态;
    printf("ddd");
    getchar();
    return 0;
}
View Code
复制代码


 2:使用bind方法

复制代码
 1 #include <string>
 2 #include <boost\thread.hpp>
 3 #include <boost/asio.hpp>
 4 #include <iostream>
 5 using namespace boost::asio;
 6 using namespace boost;
 7 int exit1 = 1;
 8 void printing(int& len, const char * str)
 9 {        
10     printf("%s", str);
11     this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
12     len++;
13 
14     exit1 = 0;
15 }
16 
17 int _tmain(int argc, _TCHAR* argv[])
18 {
19     thread(bind(printing, 2, "thread runing"));//使用bind函数将函数绑定为一个函数对象
20     while (exit1);//线程中定时后改变系统阻塞的状态;
21     printf("ddd");
22     getchar();
23     return 0;
24 }
View Code
复制代码

3:使用类的处理方式(核心哦)

说明:(1)前面两种主要是基本使用方法,而方法3已经用在了实际工程开发中,方法3主要涉及的一种状态转化的框架,在每种状态下,都有一个while死循环的进行网络或者通信口的数据读写,当满足某种条件时,进行状态的跳转;while是阻塞而线程定时器则作为后台进行状态的转化;

(2)本文的线程定时器应该叫做线程延时器,主要是在后台运行;线程成为工作者函数或者程序工作者方法;线程中延时结束后,会调用本类的成员函数作为回调处理;

(3)如果某个状态不更新,则只需要在回调中再次进行开启线程即可;

(4)当然建议使用Bind方式绑定工作者方法,否则就要设置工作函数为静态方法,还得使用reinterpret_cast强制转换指针;

(5)关于reinterpret_cast,我的理解就是"能将this指针参数强制转化为this",从而达到可以成员函数的目的;

(6)最关键的所有的操作使用的boost,本文用的编译工具是VS2013;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*线程定时器在类中使用,需要注意的是:
(1)此时必须使用“绑定成员函数”的方式给thread传入工作者线程方法,否则不能编译通过,使用这种方法好处在于工作者线程不必是静态函数;
(2)如果不采用bind方式,则必须需要将“工作者线程设置为静态函数”,另加入this指针,使用这种方法比较this指针获取比较难理解,并且工作者函数必须是静态函数;
 
*/
 
 
#include "stdafx.h"
#include <string>
#include <boost\thread.hpp>
#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
using namespace boost;
 
enum program_state
{
    state1,
    state2,
    state3,
    state4
};
class TestClassA
{
public:
    TestClassA()
    {
        state = state1;
    }
    program_state state;
    void  TimeoutPrint(int& len, const char * str);
    void  TimeoutCallbackPrint();
    void run();
    void proc_state1();
    void proc_state2();
    void static StaticTimeoutPrint(int& len, const char * str,void* This);
 
 
};
void TestClassA::TimeoutPrint(int& len, const char * str)
{
    printf("%s in\n", str);
    this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
    printf("%s out\n", str);
    //直接使用this指针就能调用回调函数
    this->TimeoutCallbackPrint();
}
void TestClassA::TimeoutCallbackPrint()
{
    this->state = state2;
    printf(" TimeoutCallbackPrint\n");
}
void TestClassA::proc_state1()
{  
    //采用绑定成员函数的方式,注意绑定成员函数时,需要一个占位符,提供类实例、引用或者指针
    thread(bind(&TestClassA::TimeoutPrint,this, 5, "thread 1"));
    while (this->state == state1)
    {
    }
}
void TestClassA::StaticTimeoutPrint(int& len, const char * str,void* This)
{
    printf("%s in\n", str);
    this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
    printf("%s out\n", str);
    //this指针需要强制转换才能访问成员函数
    ((reinterpret_cast<TestClassA*>(This)))->TimeoutCallbackPrint();
}
void TestClassA::proc_state2()
{
    //采用静态函数方式
    thread(TestClassA::StaticTimeoutPrint, 5, "thread 2",this);
    while (this->state == state2)
    {
    }
}
void TestClassA::run()
{
    while (1)
    {
        switch (this->state)
        {
            case state1:
                proc_state1();
                break;
            case state2:
                proc_state2(); break;
        }
 
    }
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    TestClassA *tc = new TestClassA();
    tc->run();
    return 0;
}

 

posted @   Mayee  阅读(1337)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示