在你的代码中,你使用了一个线程池来并行执行任务,每个线程都会对一个原子整数 s_num
进行增值操作。这段代码整体上是可行的,但仍然可以通过一些优化来提高性能和可读性。以下是一些优化建议:
1. 减少控制台输出
每次线程增加 s_num
时,都要输出当前值到控制台。控制台 I/O 操作会显著降低性能,尤其是在高并发场景下。你可以选择将输出信息缓冲,然后在所有线程完成后一次性打印。
2. 使用引用而非指针
在函数参数中直接使用引用类型而不是指针,这样更符合现代 C++ 的风格,并且减少了类型转换的复杂度。
3. 使用合理的原子变量类型
如果只需要保存非负整数,可以考虑使用无符号整数(如 std::atomic<unsigned int>
),这可能在某些情况下提供更好的性能。
优化后的代码示例
#include "CThreadPool.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <atomic>
#include <vector>
std::atomic<int> s_num(0); // 初始化原子整型为0
void func(std::atomic<int>& num) {
num.fetch_add(1);
}
int main() {
CThreadPool threadpool;
threadpool.init(5);
threadpool.start();
const int total_tasks = 10000;
// 使用向量存储输出结果,避免频繁访问 console
std::vector<std::string> output_buffer;
for (size_t i = 0; i < total_tasks; ++i) {
threadpool.exec([&output_buffer](std::atomic<int>& num){
auto id = std::this_thread::get_id();
num.fetch_add(1);
output_buffer.push_back("threadId: " + std::to_string(std::hash<std::thread::id>()(id)) +
", num = " + std::to_string(num.load()));
}, std::ref(s_num));
}
threadpool.waitForAllDone();
threadpool.stop();
// 一次性打印所有结果
for (const auto& msg : output_buffer) {
std::cout << msg << std::endl;
}
std::cout << "Final value of s_num: " << s_num.load() << std::endl;
return 0;
}
优化说明:
避免控制台的重复 I/O:我们使用一个字符串向量 (
output_buffer
) 来缓存输出信息,这样就可以减少对控制台的多次访问,提高效率。改进了参数传递方式:用引用替代指针,简化代码。
利用 Lambda 表达式:这样使得线程池的调用变得更加灵活和简洁,同时也能确保捕获上下文中的变量。
最后再打印结果:统一打印所有的信息,减轻了锁竞争和I/O瓶颈的问题。
这些改动能够有效提升程序的执行效率,同时增强了代码的可读性和维护性。在多线程编程中,合理地管理资源、减少锁争用和I/O等待是非常重要的。
内容由零声教学AI助手提供,问题来源于学员提问