1.添加头文件,文件内有python的数据类型,int目前版本已经使用long代替
#include <Python.h>
2.写一个占满CPU的函数
#include <iostream>
#include <Windows.h>
using namespace std;
//定义线程工作函数
DWORD CALLBACK TestFunc1(LPVOID lpParam) {
while (1) //死循环使CPU空转
;
}
int HIGHCPU() {
SYSTEM_INFO sysinfo; // SYSTEM_INFO 结构体用于存放收集的系统配置信息
GetSystemInfo(&sysinfo); //获取window配置信息
DWORD CPUCores = sysinfo.dwNumberOfProcessors; // 从sysinfo中拿到CPU和核心数量,这里获取的核心数不是物理核心数,而是CPU制程的线程数, 比如4核CPU,每单核CPU可并行两线程,那么就是4核8线程,得到的CPUCores数量就是8
cout << "CPU cores:" << CPUCores << endl; //打印CPUCores
DWORD nID = 0; //临时变量用于存放创建的线程ID
HANDLE *hThreads = new HANDLE[CPUCores]; // new 线程句柄的数组
for (DWORD i = 0; i < CPUCores-1; i++) {
//CreateThread 循环创建线程,句柄存放在hThreads 数组中
hThreads[i] = CreateThread(NULL, 0, TestFunc1, NULL, 0, &nID);
}
WaitForMultipleObjects(2, hThreads, true, INFINITE); //主线程阻塞等待所有线程结束
cout << "wait over" << endl; //所有线程结束后才会打印这句(实际运行不会出现这句打印,因为线程工作函数TestFunc1是死循环的永远不会结束哈哈~~~)
return 0;
}
3.添加函数以及参数
PyObject* demo1(PyObject *, PyObject* args)
{
// args参数,否则返回None
Py_INCREF(Py_None); // 引用计数,返回python时,python自动释放
if(!PyArg_ParseTuple(args,"iiO",&aint,&bint,&clist))
return Py_None;
// 定义python数据类型变量,此时引用计数加1
PyObject *pylist = PyList_New(0);
PyObject *longdata;
// 变量赋值
longdata = PyLong_FromUnsignedLong(1);
PyList_Append(datalist,longdata);
// 不返回给python的变量需要手动释放,否则内存泄漏
Py_DECREF(longdata);
return pylist;
}
PyObject* demo2(PyObject *)
{
Py_INCREF(Py_None); // 引用计数,返回python时,python自动释放
return Py_None;
}
PyObject* PYHIGHCPU(PyObject *)
{
HIGHCPU();
Py_INCREF(Py_None); // 引用计数,返回python时,python自动释放
return Py_None;
}
4.函数放在数组中
static PyMethodDef demomethod_methods[] =
{
{ "demo1", (PyCFunction)demo1, METH_VARARGS, nullptr }, //有参数
{ "demo2", (PyCFunction)demo2, METH_NOARGS, nullptr }, //没用参数
{ "PYHIGHCPU", (PyCFunction)PYHIGHCPU, METH_NOARGS, nullptr },
// Terminate the array with an object containing nulls.
{ nullptr, nullptr, 0, nullptr }
};
5.定义模块,添加函数的数组
static PyModuleDef demo_module = {
PyModuleDef_HEAD_INIT,
"demo", // Module name to use with Python import statements
"this is a demo", // Module description
0,
xlCAN_methods // Structure that defines the methods of the module
};
6.初始化,入口
PyMODINIT_FUNC PyInit_demo() {
return PyModule_Create(&demo_module);
}
7.写一个python的打包文件setup.py
from distutils.core import setup, Extension
sfc_module = Extension('demo',
sources=['module.cpp',],
include_dirs=["",""],
library_dirs=[""],
libraries=[""]
)
setup(name='demo', version='1.0',
description='Python Package with superfastcode C++ extension',
ext_modules=[sfc_module]
)
8.命令行打包
python setup.py install --user
9.创建python尝试运行
from demo import PYHIGHCPU,demo1,demo2
if __name__ == "__main__":
PYHIGHCPU()
总结:
python使用扩展C++能绕过GIL锁限制,更快的运行你的代码
参考windows占满CPU:
【C++ windows多线程使CPU 100%】_占满cpu的程序-CSDN博客
参考API:
Parsing arguments and building values — Python 3.12.0 documentation
参考参数:
PyArg_ParseTuple
"b" (integer) [char];将Python整数转换为存储在C语言char中的一个小int(tiny int)。
"h" (integer) [short int];将Python整数转换为C语言short int。
"i" (integer) [int];将Python整数转换为普通的C语言int。
"l" (integer) [long int];将Python整数转换为C语言long int。
"c" (string of length 1) [char];将长度为1的字符串表示的Python字符转换为C语言char。
"f" (float) [float];将Python浮点数转换为C语言float。
"d" (float) [double];将Python浮点数转换为C 语言double。
"D" (complex) [Py_complex];将Python复数转换为C语言Py_complex结构。
"O" (object) [PyObject *];在C对象指针中存储Python对象(不进行任何转换)。因此,C程序接收传递的实际对象。对象的引用计数没有增加。存储的指针不是空的(NULL)。