在C++中使用多线程实现触发式独立计数器的while循环逻辑
C++多线程实现独立计数器触发逻辑
问题背景
我需要实现一个计数器,当它达到特定值时启动另一个独立运行的计数器。每个计数器都有自己的目标值、初始值和增量值,原本用while循环实现递增,但现有代码存在两个问题:
- 主循环里的
currentValue永远不会精确等于2(浮点数精度缺陷),导致子循环函数根本没被调用; - 就算触发条件成立,子循环也会在主线程中执行,阻塞主循环,无法实现两个计数器并行运行的需求。
因此想用C++的多线程技术解决这个问题。
原非功能性代码
#include <stdio.h> #include <iostream> using std::cout; using std::endl; void childWhileLoop() { double number = 2; double currentValue = 0.1; while(currentValue < number) { cout << currentValue << endl; currentValue += 0.1; } } int main(int argc, char const *argv[]) { double largeNumber = 5; double currentValue = 0.1; while(currentValue < largeNumber) { cout << currentValue << endl; if(currentValue == 2) { childWhileLoop(); } currentValue += 0.1; } return 0; }
问题分析
- 浮点数精度问题:0.1属于二进制无法精确表示的浮点数,累加后
currentValue永远不会刚好等于2,触发条件永远不成立; - 单线程阻塞:就算触发条件成立,子循环会占用主线程执行,主循环会被卡住直到子循环结束,不符合“独立计数器”的并行要求。
多线程解决方案(C++11+)
使用C++标准库的<thread>实现多线程,同时修复浮点数精度问题:
#include <iostream> #include <thread> using std::cout; using std::endl; using std::thread; // 通用计数器函数,支持自定义标识、目标值、初始值、增量 void counter(const char* tag, double target, double start, double step) { double current = start; while (current < target) { cout << "[" << tag << "] " << current << endl; current += step; } cout << "[" << tag << "] 计数完成" << endl; } int main() { // 主计数器参数 const double mainTarget = 5.0; const double mainStart = 0.1; const double mainStep = 0.1; // 触发子计数器的阈值 const double triggerThreshold = 2.0; double mainCurrent = mainStart; thread childThread; // 子线程对象 while (mainCurrent < mainTarget) { cout << "[主计数器] " << mainCurrent << endl; // 用范围判断代替精确相等,避开浮点数精度坑,且确保子线程只创建一次 if (mainCurrent >= triggerThreshold - mainStep/2 && mainCurrent <= triggerThreshold + mainStep/2 && !childThread.joinable()) { // 启动子线程,并行执行子计数器逻辑 childThread = thread(counter, "子计数器", 2.0, 0.1, 0.1); } mainCurrent += mainStep; } // 等待子线程执行完毕,避免主线程提前退出导致子线程被强制销毁 if (childThread.joinable()) { childThread.join(); } cout << "[主计数器] 计数完成" << endl; return 0; }
关键说明
- 多线程核心:
std::thread是C++11引入的标准多线程工具,创建线程时直接传入要执行的函数和参数,子线程会独立并行运行; - 浮点数精度修复:用
triggerThreshold ± mainStep/2的范围判断,确保当mainCurrent接近2时触发子线程; - 线程管理:
joinable()检查线程是否已启动,避免重复创建;join()让主线程等待子线程结束,防止程序提前终止。
内容的提问来源于stack exchange,提问作者K.Sx0000
相关产品推荐
相关产品推荐

