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

摘要:
了解boost计时器#include“stdafx.h”#include<}int_Tmain(intargc;_TCHAR*argv[]){//绑定简单函数intel=2;thread(printing;ref(len));printf(“ddd”);getchar();使用绑定方法1#include<2#include&lt:4#include&llt;len;

  1:简单了解boost定时器

使用boost线程定时器作为后台线程来切换主循环程序状态方法总结第1张使用boost线程定时器作为后台线程来切换主循环程序状态方法总结第2张
#include "stdafx.h"
#include <string>
#include <boost	hread.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方法

使用boost线程定时器作为后台线程来切换主循环程序状态方法总结第3张使用boost线程定时器作为后台线程来切换主循环程序状态方法总结第4张
 1 #include <string>
 2 #include <boost	hread.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)此时必须使用“绑定成员函数”的方式给thread传入工作者线程方法,否则不能编译通过,使用这种方法好处在于工作者线程不必是静态函数;
(2)如果不采用bind方式,则必须需要将“工作者线程设置为静态函数”,另加入this指针,使用这种方法比较this指针获取比较难理解,并且工作者函数必须是静态函数;

*/


#include "stdafx.h"
#include <string>
#include <boost	hread.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
", str);
	this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
	printf("%s out
", str);
	//直接使用this指针就能调用回调函数
	this->TimeoutCallbackPrint();
}
void TestClassA::TimeoutCallbackPrint()
{
	this->state = state2;
	printf(" TimeoutCallbackPrint
");
}
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
", str);
	this_thread::sleep_for(chrono::seconds(len));//线程中阻塞定时后改变系统状态
	printf("%s out
", 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;
}

免责声明:文章转载自《使用boost线程定时器作为后台线程来切换主循环程序状态方法总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇最近使用 .NET Core 遇到的一些坑SaaS应用十大关键NFR下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#基本面试题

重写和重载 重写: 要求:(三大同)参数相同,方法名相同,返回值相同 关键字:基类函数用virtual修饰,派生类用override修饰 注意:不能重写非虚方法或静态方法 重载: 要求:在同一作用域,可以存在相同的函数名,不同参数列表的函数,这组函数称为重载函数 其他 WebAPI和MVC的区别 1、MVC主要用于建站,WebAPI主要用于构建http...

tcpip详解笔记(15) TCP协议连接过程

TCP是一个面向连接的协议,在发送数据之前,双方必须通过三次握手协议建立连接,而在终止连接的时候执行4次握手协议。 连接建立和终止 先看一下telnet连接服务器80端口的抓包:   上图由wireshark抓取,并显示了TCP状态图(注意:由于网络阻塞,发生了丢包现象,4是对2的重发,而5是对4的响应(同3相同))。 根据上图可以看到建立一个TCP连接的...

spring boot 访问页面(静态页面及jsp页面)

1.访问静态html 页面 ,使用官网提供的demo和还是一直访问不到html ,后来使用thymeleaf 模板,引入了依赖,发现html也能正常访问了 a) main/resource  文件夹下新建一个templates 文件夹 b) 添加maven 依赖 c) 编写控制方法 启动之后访问 localhost:prot/index 就能访问到页...

【STM32H7教程】第13章 STM32H7启动过程详解

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第13章       STM32H7启动过程详解 本章教程主要跟大家讲STM32H7的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的部分。启动过程相对来说...

[转]如何定位Release程序崩溃原因

1       案例描述作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭。请与您的供应商联系。呵呵,这句微软的“名言”,恐怕是程序员最怕见也最常见的东西了。 在一个大型软件的测试过程中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。...

Segmentation fault (core dumped) 错误的一种解决场景

错误类型 Segmentation fault (core dumped) 产生原因 Segmentation fault 段错误。 Core Dump 核心转储(是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件。这种信息往往用于调试),其实“吐核”这个词形容的很恰当,就是核心内存吐出来。 出...