使用c++;在python对象内声明的std::mutex
简短问题: 在使用malloc获取相应内存后,如何初始化结构中的std::mutex 更多详情: 我试图用一个后台线程创建一个python模块 我创建和运行线程没有任何问题,但是如果我尝试使用Python对象中存储的互斥锁,它就会崩溃 如果我在cpp文件的头部定义互斥体,它就可以工作。但我更愿意将其存储在设备结构中 在我的PyDevice.h中使用c++;在python对象内声明的std::mutex,python,c++,multithreading,c++11,Python,C++,Multithreading,C++11,简短问题: 在使用malloc获取相应内存后,如何初始化结构中的std::mutex 更多详情: 我试图用一个后台线程创建一个python模块 我创建和运行线程没有任何问题,但是如果我尝试使用Python对象中存储的互斥锁,它就会崩溃 如果我在cpp文件的头部定义互斥体,它就可以工作。但我更愿意将其存储在设备结构中 在我的PyDevice.h中 #include <Python.h> #include "structmember.h" typedef struct sSharedD
#include <Python.h>
#include "structmember.h"
typedef struct sSharedData
{
bool mStop;
} sSharedData;
typedef struct sDevice
{
PyObject_HEAD
std::thread mDataThread;
std::mutex mDataThreadMutex;
sSharedData mDataThreadSharedData;
} sLeddarDevice;
PyObject *StartDataThread( sLeddarDevice *self, PyObject *args );
PyObject *StopDataThread( sLeddarDevice *self, PyObject *args );
static PyMethodDef Device_methods[] =
{
{ "StartDataThread", ( PyCFunction )StartDataThread, METH_NOARGS, "Start the thread." },
{ "StopDataThread", ( PyCFunction )StopDataThread, METH_NOARGS, "Stop the thread." },
{ NULL } //Sentinel
};
static PyMemberDef Device_members[] =
{
{ NULL } //Sentinel
};
static PyTypeObject LeddarDeviceType =
{
PyObject_HEAD_INIT( NULL )
0, //ob_size
"LeddarPy.Device", //tp_name
sizeof( sDevice ), //tp_basicsize
0, //tp_itemsize
( destructor )Device_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
0, //tp_compare
0, //tp_repr
0, //tp_as_number
0, //tp_as_sequence
0, //tp_as_mapping
0, //tp_hash
0, //tp_call
0, //tp_str
0, //tp_getattro
0, //tp_setattro
0, //tp_as_buffer
Py_TPFLAGS_DEFAULT, //tp_flags
"Device object.", // tp_doc
0, //tp_traverse
0, //tp_clear
0, //tp_richcompare
0, //tp_weaklistoffset
0, //tp_iter
0, //tp_iternext
Device_methods, //tp_methods
Device_members, //tp_members
0, //tp_getset
0, //tp_base
0, //tp_dict
0, //tp_descr_get
0, //tp_descr_set
0, //tp_dictoffset
0, //tp_init
0, //tp_alloc
Device_new, //tp_new
};
每当我尝试使用self->mDataThreadMutex.lock()
时,它就会崩溃
我不确定互斥体是否被正确初始化,我更习惯于pHoTrimeX,需要手动初始化它。
python是用C编写的,因此它不会为你运行C++构造函数/析构函数。没有它们,std::mutex
只是一个毫无意义的结构,在使用时会崩溃。您需要的是某个地方(在分配self
?)之后):
第二行在self
上调用sLeddarDevice
的构造函数,而不分配内存。该构造函数也将调用每个成员的构造函数
完成后还必须手动调用析构函数:self->~sLeddarDevice()代码>
当C++与Python相结合时,你应该做<强>永远>强。否则,在最好的情况下,您将泄漏内存。在更坏的情况下,遇到随机崩溃的未定义行为。 Python是用C编写的,因此它不会为您运行C++构造函数/析构函数。没有它们,
std::mutex
只是一个毫无意义的结构,在使用时会崩溃。您需要的是某个地方(在分配self
?)之后):
第二行在self
上调用sLeddarDevice
的构造函数,而不分配内存。该构造函数也将调用每个成员的构造函数
完成后还必须手动调用析构函数:self->~sLeddarDevice()代码>
当C++与Python相结合时,你应该做<强>永远>强。否则,在最好的情况下,您将泄漏内存。在更糟糕的情况下,会遇到随机崩溃的未定义行为。StackOverflow不是gdb
-as-a-service。请发布StackOverflow不是gdb
-as-a-service。请发布一个设备,当python对象被删除时调用dealloc,我可以从那里调用析构函数?@davidevy是的,你可以也应该这样做。注意,我不确定Python的tp_alloc
和tp_free
将如何与C++的构造函数和析构函数一起工作。C++和C代码的结合有时很难。使用构造函数工作(没有初始化列表),使用DeSrutor导致崩溃。一个小细节,新(自我)意味着什么?这是我第一次看到有人用这个way@DavidLevy它被称为“新安置”。它只运行构造函数而不分配内存(您将指针传递到它应该调用构造函数的位置)。查看链接和/或谷歌搜索。对于析构函数:您在tp_free
之前调用过它吗?哦,请注意,如果您不.join()
线程或将其分离,析构函数将崩溃。删除python对象时调用Device_dealloc,我可以从那里调用析构函数?@davidevy是的,您可以也应该这样做。注意,我不确定Python的tp_alloc
和tp_free
将如何与C++的构造函数和析构函数一起工作。C++和C代码的结合有时很难。使用构造函数工作(没有初始化列表),使用DeSrutor导致崩溃。一个小细节,新(自我)意味着什么?这是我第一次看到有人用这个way@DavidLevy它被称为“新安置”。它只运行构造函数而不分配内存(您将指针传递到它应该调用构造函数的位置)。查看链接和/或谷歌搜索。对于析构函数:您是否在tp_free
之前调用过它?哦,请注意,如果您不.join()
线程或将其分离,析构函数将崩溃。
#include "LeddarPyDevice.h"
//Constructor
PyObject *Device_new( PyTypeObject *type, PyObject *args, PyObject *kwds )
{
sLeddarDevice *self;
self = ( sLeddarDevice * )type->tp_alloc( type, 0 );
if( self != nullptr )
{
self->mDataThreadSharedData.mStop = false;
}
return ( PyObject * )self;
}
//Destructor
void Device_dealloc( sLeddarDevice *self )
{
DebugTrace( "Destructing device." );
Py_TYPE( self )->tp_free( ( PyObject * )self );
}
PyObject *StartDataThread( sLeddarDevice *self, PyObject *args )
{
DebugTrace( "Starting thread" );
self->mDataThreadMutex.lock();
self->mDataThreadSharedData.mStop = false;
self->mDataThreadMutex.unlock();
self->mDataThread = std::thread( DataThread, self );
Py_RETURN_TRUE;
}
self = ( sLeddarDevice * )type->tp_alloc( type, 0 );
new (self) sLeddarDevice {};