这个多线程的代码算不上特别完善,还有很大的优化空间
thread_utils.h
#pragma once
#include <iostream> // 标准输入输出流
#include <atomic> // 原子操作
#include <thread> // 线程支持
#include <unistd.h> // POSIX API
#include <sys/syscall.h> // 系统调用
namespace Common {
// 线程工具函数命名空间,提供线程相关的实用函数
/**
* 设置当前线程的CPU亲和度(CPU亲和性和线程绑定)
* 将当前线程固定到指定的CPU核心上运行,减少线程在不同CPU间切换带来的上下文切换开销
* 在低延迟应用中非常重要,可以减少缓存乱序和上下文切换开销
*
* @param core_id 要绑定的CPU核心ID,从0开始
* @return 是否成功设置CPU亲和度
*/
inline auto setThreadCore(int core_id) noexcept {
cpu_set_t cpuset; // CPU集合数据结构
CPU_ZERO(&cpuset); // 初始化CPU集合,清除所有CPU
CPU_SET(core_id, &cpuset); // 将指定ID的CPU添加到集合中
// 调用pthread函数设置线程的CPU亲和性
// pthread_self()获取当前线程的ID
// 返回0表示成功
return (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == 0);
}
/**
* 创建并启动线程
* 创建一个新线程,设置其CPU亲和性,指定名称,并在其上运行给定的函数
* 使用了可变参数模板,可以接受任意类型和数量的参数
*
* @param core_id 要绑定的CPU核心ID,如果为-1则不设置亲和性
* @param name 线程名称,仅用于日志记录
* @param func 要在新线程中执行的函数
* @param args 传递给函数的参数
* @return 新创建的线程对象指针
*/
template<typename T, typename... A>
inline auto createAndStartThread(int core_id, const std::string &name, T &&func, A &&... args) noexcept {
// 创建新线程,使用lambda函数包装要执行的任务
auto t = new std::thread([&]() {
// 如果指定了有效的核心ID,则设置线程的CPU亲和性
if (core_id >= 0 && !setThreadCore(core_id)) {
// 如果设置失败,输出错误并终止程序
std::cerr << "Failed to set core affinity for " << name << " " << pthread_self() << " to " << core_id << std::endl;
exit(EXIT_FAILURE);
}
// 输出设置成功的日志
std::cerr << "Set core affinity for " << name << " " << pthread_self() << " to " << core_id << std::endl;
// 使用完美转发调用用户定义的函数,保留参数的值类型/引用类型
std::forward<T>(func)((std::forward<A>(args))...);
});
// 等待1秒,确保线程成功启动
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(1s);
return t;
}
}例子1:
#include "thread_utils.h" // 假设包含上述内存池和线程工具函数的头文件
#include <iostream>
#include <vector>
// 任务1:计算平方
void calculateSquare(int num) {
for (int i = 0; i < 1000000; ++i) {
std::cout << "Square of " << num << " is " << num*num
<< " (Core: " << sched_getcpu() << ")" << std::endl;
}
}
// 任务2:计算立方
void calculateCube(int num) {
for (int i = 0; i < 1000000; ++i) {
int cube = i*i*i;
}
std::cout << "Cube of " << num << " is " << num*num*num
<< " (Core: " << sched_getcpu() << ")" << std::endl;
}
// 任务2:计算立方1
void calculateCube1(int num) {
for (int i = 0; i < 1000000; ++i) {
int cube = num*num*num;
}
std::cout << "Cube1 of " << num << " is " << num*num*num
<< " (Core: " << sched_getcpu() << ")" << std::endl;
}
// 任务2:计算立方2
void calculateCube2(int num) {
for (int i = 0; i < 1000000; ++i) {
int cube = num*num*num;
}
std::cout << "Cube2 of " << num << " is " << num*num*num
<< " (Core: " << sched_getcpu() << ")" << std::endl;
}
// 任务3:打印系统时间
void printSystemTime() {
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
std::cout << "Current time: " << std::ctime(&now_time)
<< " (Core: " << sched_getcpu() << ")" << std::endl;
}
int main() {
// 创建3个线程,分别绑定到不同核心
auto t1 = Common::createAndStartThread(2, "SquareThread", calculateSquare, 5);
auto t2 = Common::createAndStartThread(2, "CubeThread", calculateCube, 7);
auto t3 = Common::createAndStartThread(2, "TimeThread", printSystemTime);
auto t4 = Common::createAndStartThread(2, "CubeThread1", calculateCube1, 8);
auto t5 = Common::createAndStartThread(2, "CubeThread2", calculateCube2, 9);
// 等待所有线程完成
t1->join();
t2->join();
t3->join();
t4->join();
t5->join();
delete t1;
delete t2;
delete t3;
delete t4;
delete t5;
return 0;
}例子2
#include "thread_utils.h"
auto dummyFunction(int a, int b, bool sleep) {
std::cout << "dummyFunction(" << a << "," << b << ")" << std::endl;
std::cout << "dummyFunction output=" << a + b << std::endl;
if(sleep) {
std::cout << "dummyFunction sleeping..." << std::endl;
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(5s);
}
std::cout << "dummyFunction done." << std::endl;
}
int main(int, char **) {
using namespace Common;
auto t1 = createAndStartThread(-1, "dummyFunction1", dummyFunction, 12, 21, true);
auto t2 = createAndStartThread(1, "dummyFunction2", dummyFunction, 15, 51, true);
std::cout << "main waiting for threads to be done." << std::endl;
t1->join();
t2->join();
std::cout << "main exiting." << std::endl;
return 0;
}
系统当前共有 481 篇文章