C++多线程打包成so给JAVA后端(Ubuntu)<3>

单一线程的启动已经在前两个章节介绍过了,下面我为大家分享如何进行多线程的创建!

我所应用的场景:so来处理硬件发送的数据,因为一些不确定操作缘故会导致操作模型时带动多个点被触发,此时需要使用多个线程对这个触发点做判断,在500ms内操作未发生变化时,表示该操作触发有效,在500ms内触发状态变化,则忽略此操作。

实现难点:

1:如何选择多线程 or 线程池?

2:使用纯C++环境如何自己实现线程池启动多线程?

3:当连接多个模型并同时出发一个操作点时,如何保证每个线程唯一性?

4:如何立即停止正在运行的多线程?

带着这些问题,我来为大家详细介绍我在so中使用的多线程机制!

确定线程启动方案

线程池和多线程不是同一个层次的概念,很多对线程不清楚的同学会混淆这两者。

针对我应用的场景,属于大量短生命周期任务,并且处理的抖动硬件操作不是很多,可以采用线程池的方式。

我的这种方式仅作为Demo使用,当写的so进行一拖多时,会有问题,作为学习参考资料,还是非常不错的。

纯C++方式实现

业务逻辑:接收到硬件某条消息后,开启500ms的定时线程,如果在500ms内被再次触发,表明操作无效,达到500ms后,表示操作有效。

根据这个业务逻辑,使用C++的线程池方式来实现吧!

单个任务触发逻辑

所谓的多线程池操作,说白了就是把多个相同的线程放到一个地方进行管理,那么首要任务就是要先实现一个线程的完整流程。

请看完整代码:

cpp 复制代码
class ThreadTask
{
public:
	//定义回调函数,当线程结束后被回调(int:参数类型,int:线程运行的毫秒值)
	using CallbackThreadTaskFinished = std::function<void(std::string, int, int)>;

	ThreadTask()
	{
		m_bStopThread = false;
	}

	//设置线程超时时间
	void setThreadTimeout(std::string sModeId, int nThreadType, int nTime, bool bBreakSendMsg = false)
	{
		m_sModeId = sModeId;
		m_nThreadType = nThreadType;
		m_nTimeout = nTime;
		m_bBreakSendMsg = bBreakSendMsg;
	}
	//设置:回调函数
	void setCallback(CallbackThreadTaskFinished callback)
	{
		m_callback = callback;
	}

	//执行任务
	void run() {
		int sleepCount = 0; // 记录实际休眠次数(每次100ms)
		bool bTimeout = false; //超时了
		while (!m_bStopThread) {
			std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 先休眠再判断
			sleepCount++; // 累计休眠次数
			// 检查线程是否自然结束,当m_nTimeout> 0时进行判断,当 < 0 时,需要外界停止
			if (m_nTimeout > 0 && sleepCount * 100 >= m_nTimeout){
				bTimeout = true;
				break; //线程完毕,退出线程
			}
			
		}
		//线程结束时执行回调函数
		if (m_bBreakSendMsg && m_callback)
		{
			m_callback(m_sModeId, m_nThreadType, sleepCount);
		}
		else if (m_callback && bTimeout)
		{
			//线程自然结束后发送回调
			m_callback(m_sModeId, m_nThreadType, sleepCount);
		}
	}

	//停止标识
	void StopThread() {
		m_bStopThread = true;
	}

	//获取:当前任务标识
	int getTypeId() {
		return m_nThreadType;
	}
private:
	std::string m_sModeId; //模型类型
	int m_nTimeout; //超时时间
	int m_nThreadType; //记录线程类型,用于回调数据
	bool m_bBreakSendMsg; //打断线程是否发送消息,默认不发送
	std::atomic<bool> m_bStopThread; //强制停止标志
	CallbackThreadTaskFinished m_callback; //回调函数
};

注释写的非常清楚,我这里就不再详细讲述了。

今天就为大家主要介绍如何单个使用一个线程任务的逻辑,如果有问题可以评论留言哟,下一章节为大家介绍如何在线程池中调用这个Task~

我是糯诺诺米团,一名C++程序媛~

相关推荐
Demon--hx1 小时前
jsoncpp 核心概念梳理:命名空间、Value 容器与格式化输出
c++
不是万能的豆学长4 小时前
filetidy 文件整理助手:一键归类 + 规范重命名(Python 零依赖单文件工具)
大数据·开发语言·python·技术美术
时间静止不是简史4 小时前
生产事故排查:Redis 宕机导致补偿队列消费线程死亡,通话录音未上送业务平台
java·redis
2301_32241428047 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
懂点Tech8 小时前
ctfshow MISC入门图片篇(信息附加):misc41解题思路
开发语言·python
金銀銅鐵9 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
catchadmin9 小时前
PHP 8.7 协程新提案 让跨协程代码共享请求身份
开发语言·php
福建佰胜张工9 小时前
SMC 薄型气爪 MHF2-16D1 深度解析:平行开闭、低剖面结构在自动化装配中的选型与落地
java·服务器·安全·自动化
念何架构之路9 小时前
go-grpc设计思想
开发语言·后端·golang
catoop9 小时前
API Key 设计与安全生成方案:结构拆解、数据库设计与 Java 实现
java·数据库·安全