C++多线程实现绑定CPU的方法详解

 更新时间:2023年05月22日 08:37:36   作者:微小冷  
这篇文章主要为大家详细介绍了C++如何利用多线程实现绑定CPU,文中的示例代码简洁易懂,具有一定的学习价值,感兴趣的小伙伴可以跟随小编一起了解一下

Windows多线程

windows.h中提供了多线程解决方案,创建多线程的函数为

//返回值:一个HANDLE类型的值,表示线程的句柄,可用于等待线程等函数
HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes, // 不用管,一般为NULL
  SIZE_T                  dwStackSize,        // 堆栈大小,一般为0,表示默认值
  LPTHREAD_START_ROUTINE  lpStartAddress,     // 函数指针
  __drv_aliasesMem LPVOID lpParameter,        // 参数指针
  DWORD                   dwCreationFlags,    // 不用管,一般为0
  LPDWORD                 lpThreadId          // 线程id,一般设为NULL
);

为了理解这个函数,下面举一个最简单的例子

#include<iostream>
#include<windows.h>

// 编写了一个我的线程函数
DWORD WINAPI MyThread(LPVOID ps)
{
	int *n = (int *)ps;
	for (int i = 0; i < 3; ++i)
		printf("执行线程%d, i=%d\n", n[0], i);
	return 0L;
}

int main()
{
	// 创造线程
	int id1 = 1, id2=2;
	CreateThread(NULL, 0, MyThread, &id1, 0, NULL);
	CreateThread(NULL, 0, MyThread, &id2, 0, NULL);
	system("PAUSE");
	return 0;
}

其中,MyThread是一个用于创造新线程的函数,其输入参数ps是一个LPVOID类型的指针,在参数传入后,将这个指针转为整形指针(int *),然后将其赋给另一个整形指针n,然后在for循环中引用这个整形指针。

在main函数中,通过CreateThread函数创建一个线程并执行,其中执行的函数为MyThread,传入的参数为id1, id2的地址。执行后的结果为

执行线程2, i=0
执行线程1, i=0
执行线程1, i=1
执行线程1, i=2
执行线程2, i=1
执行线程2, i=2
请按任意键继续. . .

windows调度与绑定CPU

作为成熟的操作系统,Windows为了更加充分利用CPU,会动态分配线程占用的CPU资源,以确保每个CPU核心不过累;另一方面,Intel作为成熟的CPU,为了充分考虑性能和能耗之间的均衡,当CPU没有满负荷运行的时候会自动降频。

这两个合在一起就是,Windows动态分配CPU核心,让每个CPU都不过载;然后Intel动态规划能耗,让每个核心都降频。于是CPU的频率越降越低,Windows占用的资源越来越少,于是性能越来越差。

上面这个描述当然略显夸张了,但道理是这么个道理,为了验证这一点,可以将上面的MyThread函数稍作改动,

DWORD WINAPI MyThread(LPVOID ps)
{
    int* n = (int*)ps;
    int cpu = GetCurrentProcessorNumber();
    for (int i = 0; i < 5; ++i) {
        printf("在CPU%d上执行线程%d, i=%d\n", cpu, n[0], i);
        Sleep(100);
    }
    return 0L;
}

这样就可以查看每次执行线程时所使用的CPU,发现每次运行时使用的CPU是随机的。

通过windows.h中的SetThreadAffinityMask来手动分配CPU,使用方法非常简单

int main()
{
    // 创造线程
    int id1 = 1, id2=2;
    auto th1 = CreateThread(NULL, 0, MyThread, &id1, 0, NULL);
    SetThreadAffinityMask(th1, 0x01);
    auto th2 = CreateThread(NULL, 0, MyThread, &id2, 0, NULL);
    SetThreadAffinityMask(th2, 0x02);
    // 记得等待线程结束
    system("PAUSE");
    return 0;
}

效果如下

在CPU0上执行线程1, i=0
在CPU1上执行线程2, i=0
请按任意键继续. . . 在CPU1上执行线程2, i=1
在CPU0上执行线程1, i=1
在CPU0上执行线程1, i=2
在CPU1上执行线程2, i=2
在CPU1上执行线程2, i=3
在CPU0上执行线程1, i=3
在CPU1上执行线程2, i=4
在CPU0上执行线程1, i=4

到此这篇关于C++多线程实现绑定CPU的方法详解的文章就介绍到这了,更多相关C++多线程绑定CPU内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文搞懂C++多态的用法

    一文搞懂C++多态的用法

    C++多态是在继承的基础上实现的,了解多态之前我们需要掌握一定的C++继承的知识,本文将介绍C++中多态的概念,构成条件以及用法,感兴趣的可以学习一下
    2022-04-04
  • C++ const的使用及this指针常方法(面试最爱问的this指针)

    C++ const的使用及this指针常方法(面试最爱问的this指针)

    这篇文章主要介绍了C++ const的使用,this指针,常方法(面试最爱问的this指针),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C/C++实现个人收支系统的示例代码

    C/C++实现个人收支系统的示例代码

    这篇文章主要介绍了C/C++实现个人收支系统,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 关于C++静态成员函数访问非静态成员变量的问题

    关于C++静态成员函数访问非静态成员变量的问题

    静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员
    2013-10-10
  • C++ 组合 (Composition)的介绍与实例

    C++ 组合 (Composition)的介绍与实例

    这篇文章主要给大家介绍了关于C++ 组合(Composition)的相关资料,组合就是将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。需要的朋友可以参考下
    2021-05-05
  • C++实现酒店管理系统

    C++实现酒店管理系统

    这篇文章主要为大家详细介绍了C++实现酒店管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 基于Matlab制作一个数独求解器

    基于Matlab制作一个数独求解器

    这篇文章主要为大家详细介绍了如何利用Matlab制作一个数独求解器,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下
    2022-05-05
  • C语言的程序环境与预处理你真的了解吗

    C语言的程序环境与预处理你真的了解吗

    这篇文章主要为大家详细介绍了C语言的程序环境与预处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言中的自定义类型之结构体与枚举和联合详解

    C语言中的自定义类型之结构体与枚举和联合详解

    今天我们来学习一下自定义类型,自定义类型包括结构体、枚举、联合体,小编觉得挺不错的,现在就分享给大家,也给大家做个参考
    2022-06-06
  • C++归并算法实例

    C++归并算法实例

    这篇文章主要介绍了C++归并算法,实例分析了C++实现基于归并算法合并线性表的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论