Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从boost线程调用Python? 我有一个Python应用程序,它调用C++ Boost Python库,并且都是有效的。但是,我有一个回调C++到Python场景,其中来自Boost线程的C++调用Python,并且在C++端得到访问冲突。如果我使用python线程执行完全相同的回调,它将非常有效。因此,我怀疑,我不能简单地使用Boost线程从C++中回调Python,但需要额外做一些工作, < P>最有可能的罪魁祸首是,当调用Python代码时,(吉尔)没有被一个线程所保存,导致了未定义的行为。验证所有进行直接或间接Python调用的路径,在调用Python代码之前获取GIL_Python_C++_Multithreading_Boost Python_Boost Thread - Fatal编程技术网

如何从boost线程调用Python? 我有一个Python应用程序,它调用C++ Boost Python库,并且都是有效的。但是,我有一个回调C++到Python场景,其中来自Boost线程的C++调用Python,并且在C++端得到访问冲突。如果我使用python线程执行完全相同的回调,它将非常有效。因此,我怀疑,我不能简单地使用Boost线程从C++中回调Python,但需要额外做一些工作, < P>最有可能的罪魁祸首是,当调用Python代码时,(吉尔)没有被一个线程所保存,导致了未定义的行为。验证所有进行直接或间接Python调用的路径,在调用Python代码之前获取GIL

如何从boost线程调用Python? 我有一个Python应用程序,它调用C++ Boost Python库,并且都是有效的。但是,我有一个回调C++到Python场景,其中来自Boost线程的C++调用Python,并且在C++端得到访问冲突。如果我使用python线程执行完全相同的回调,它将非常有效。因此,我怀疑,我不能简单地使用Boost线程从C++中回调Python,但需要额外做一些工作, < P>最有可能的罪魁祸首是,当调用Python代码时,(吉尔)没有被一个线程所保存,导致了未定义的行为。验证所有进行直接或间接Python调用的路径,在调用Python代码之前获取GIL,python,c++,multithreading,boost-python,boost-thread,Python,C++,Multithreading,Boost Python,Boost Thread,GIL是CPython解释器周围的互斥体。此互斥锁防止在Python对象上执行并行操作。因此,在任何时间点,最多允许一个线程(即获得GIL的线程)对Python对象执行操作。当存在多个线程时,在不持有GIL的情况下调用Python代码会导致未定义的行为 在Python文档中,有时将P> C或C++线程称为异类线程。Python解释器无法控制外来线程。因此,外来线程负责管理GIL,以允许与Python线程并发或并行执行。必须认真考虑: 堆栈展开(如Boost.Python)可能会引发异常 对Py

GIL是CPython解释器周围的互斥体。此互斥锁防止在Python对象上执行并行操作。因此,在任何时间点,最多允许一个线程(即获得GIL的线程)对Python对象执行操作。当存在多个线程时,在不持有GIL的情况下调用Python代码会导致未定义的行为

在Python文档中,有时将P> C或C++线程称为异类线程。Python解释器无法控制外来线程。因此,外来线程负责管理GIL,以允许与Python线程并发或并行执行。必须认真考虑:

  • 堆栈展开(如Boost.Python)可能会引发异常
  • 对Python的间接调用,如复制构造函数或析构函数
一个解决方案是使用一个了解GIL管理的自定义类型包装Python回调


使用类来管理GIL提供了一个优雅的异常安全解决方案。例如,使用下面的
with\u gil
类,当创建
with\u gil
对象时,调用线程获取gil。当
with_gil
对象被破坏时,它将恢复gil状态

//@施工时将获得GIL的简短守卫,以及
///破坏后恢复其状态。
与_gil一起上课
{
公众:
使用_gil(){state_uu=PyGILState_sure();}
~with_gil(){PyGILState_Release(state_uu);}
with_gil(const with_gil&)=删除;
with_gil&运算符=(const with_gil&)=删除;
私人:
皮吉州;
};
及其用法:

{
与_gil gil;//获取gil。
//执行Python调用,可能会抛出
}//还原GIL。
由于能够通过
和_GIL
管理GIL,下一步是创建一个适当管理GIL的函子。以下
py\u callable
类将包装一个
boost::python::object
,并获取调用python代码的所有路径的GIL:

//@brief Helper类型,用于管理python回调的GIL。
///
///@detail GIL管理:
///*复制`boost::python`对象时获取GIL
///*将管理新构造的“python::object”
///通过“共享”ptr。因此,可以复制它而不拥有它
///吉尔。但是,自定义删除程序将获取
///删除期间的GIL
///*当调用'py_callable'时(运算符()),它将获取
///然后GIL将委托给托管的`python::对象`
类py_可调用
{
公众:
///@假定调用方已锁定GIL的简短构造函数。
py_可调用(const boost::python::object&object)
{
与_gil gil;
对象重置(
//吉尔锁上了,所以复制是安全的。
新的boost::python::object{object},
//删除对象时,使用自定义删除器保留GIL。
[](boost::python::object*object)
{
与_gil gil;
删除对象;
});
}
//使用默认的复制构造函数和赋值运算符。
py_callable(const py_callable&)=默认值;
py_可调用&运算符=(const py_可调用&)=默认值;
模板
void运算符()(Args…Args)
{
//在调用python对象时锁定GIL。
与_gil gil;
(*Objuts*)(STD::FoePythPython扩展调用Python对象作为C++线程的回调:

\include//std::shared\u ptr
#包括//std::此线程,std::线程
#include//std::forward
#包括
///@建造时将获得GIL的简短守卫,以及
///破坏后恢复其状态。
与_gil一起上课
{
公众:
使用_gil(){state_uu=PyGILState_sure();}
~with_gil(){PyGILState_Release(state_uu);}
with_gil(const with_gil&)=删除;
with_gil&运算符=(const with_gil&)=删除;
私人:
皮吉州;
};
///@brief Helper类型,用于管理python回调的GIL。
///
///@detail GIL管理:
///*复制`boost::python`对象时获取GIL
///*将管理新构造的“python::object”
///通过“共享”ptr。因此,可以复制它而不拥有
///GIL。但是,自定义删除程序将获得
///删除期间的GIL
///*当调用'py_callable'时(运算符()),它将获取
///然后GIL将委托给托管的`python::对象`
类py_可调用
{
公众:
///@假定调用方已锁定GIL的简短构造函数。
py_可调用(const boost::python::object&object)
{
与_gil gil;
对象重置(
//吉尔锁上了,所以复制是安全的。
新的boost::python::object{object},
//删除对象时,使用自定义删除器保留GIL。
[](boost::python::object*object)
{
与_gil gil;
删除对象;
});
}
//使用默认的复制构造函数和赋值运算符。
py_callable(const py_callable&)=默认值;
py_可调用&运算符=(const py_可调用&)=默认值;
模板
无效操作器