python C++扩展

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)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值