从Python代码返回C ++时,Python PyGILState_ {Ensure / Release}导致段错误
更新
嗯,看起来好像在调用PyGILState_Ensure()之前就添加了PyEval_InitThreads()。我急于想办法,将我的“悬挂”错误地归因于PyEval_InitThreads()。
但是,在阅读了一些Python文档之后,我想知道这是否是正确的解决方案。
当未知哪个线程(如果有)当前具有全局解释器锁时,调用此函数是不安全的。
首先,我正在研究一些修改的GNU Radio代码-
特别是修改的gr_bin_statistics_f块。现在,有一个错误报告(尽管是一个旧报告),几乎可以描述我的确切情况。
http://gnuradio.org/redmine/issues/show/199
现在,在错误报告中提到的usrp_spectrum_sense.py调用gr_bin_statistics_f(C
++),然后定期调用Python以重新调整USRP(无线电)。
调用Python代码时,会发生以下情况:
PyGILState_STATE d_gstate;
d_gstate = PyGILState_Ensure();
// call python code
PyGILState_Release(d_gstate);
因此,一旦我们从Python代码返回,则在调用PyGILState_Release(d_gstate)时会发生分段错误。尽管我的代码与原始的gr_bin_statistics_f之间存在差异,但似乎没有任何远程关系。
我读到在PyGILState_Ensure()解决某些问题之前调用PyEval_InitThreads(),但这只会导致程序挂起。
谁能为我阐明这一点?还是只是将消息发送到GNU Radio邮件列表的时间?
在Fedora 14 x86_64上使用Python2.7。
这是GDB回溯:
(gdb) c
Continuing.
[New Thread 0x7fabd3a8d700 (LWP 23969)]
[New Thread 0x7fabd328c700 (LWP 23970)]
[New Thread 0x7fabd2a8b700 (LWP 23971)]
[New Thread 0x7fabd228a700 (LWP 23972)]
[New Thread 0x7fabd1a89700 (LWP 23973)]
[New Thread 0x7fabd1288700 (LWP 23974)]
[New Thread 0x7fabd0a87700 (LWP 23975)]
[New Thread 0x7fabbbfff700 (LWP 23976)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fabbbfff700 (LWP 23976)]
0x00000036b3e0db00 in sem_post () from /lib64/libpthread.so.0
(gdb) bt
#0 0x00000036b3e0db00 in sem_post () from /lib64/libpthread.so.0
#1 0x00000036c1317679 in PyThread_release_lock () from /usr/lib64/libpython2.7.so.1.0
#2 0x00007fabd6159c1f in ~ensure_py_gil_state (this=0x2dc6fc0, x=887000000)
at gnuradio_swig_py_general.cc:5593
#3 gr_py_feval_dd::calleval (this=0x2dc6fc0, x=887000000) at gnuradio_swig_py_general.cc:5605
#4 0x00007fabd77c4b6e in gr_noise_level_f::tune_window (this=0x2db3ca0,
target_freq=) at gr_noise_level_f.cc:97
#5 0x00007fabd77c554b in gr_noise_level_f::work (this=0x2db3ca0, noutput_items=7,
input_items=, output_items=)
at gr_noise_level_f.cc:115
#6 0x00007fabd7860714 in gr_sync_block::general_work (this=0x2db3ca0,
noutput_items=, ninput_items=,
input_items=, output_items=) at gr_sync_block.cc:64
#7 0x00007fabd7846ce4 in gr_block_executor::run_one_iteration (this=0x7fabbbffed90)
at gr_block_executor.cc:299
#8 0x00007fabd7864332 in gr_tpb_thread_body::gr_tpb_thread_body (this=0x7fabbbffed90, block=...)
at gr_tpb_thread_body.cc:49
#9 0x00007fabd785cce7 in operator() (function_obj_ptr=...) at gr_scheduler_tpb.cc:42
#10 operator() (function_obj_ptr=...)
at /home/tja/Research/energy/detector/gnuradio-3.3.0/gruel/src/include/gruel/thread_body_wrapper.h:49
#11 boost::detail::function::void_function_obj_invoker0, void>::invoke (function_obj_ptr=...) at /usr/include/boost/function/function_template.hpp:153
---Type to continue, or q to quit---
#12 0x00007fabd74914ef in operator() (this=)
at /usr/include/boost/function/function_template.hpp:1013
#13 boost::detail::thread_data >::run (this=)
at /usr/include/boost/thread/detail/thread.hpp:61
#14 0x00007fabd725ca55 in thread_proxy () from /usr/lib64/libboost_thread-mt.so.1.44.0
#15 0x00000036b3e06d5b in start_thread () from /lib64/libpthread.so.0
#16 0x00000036b3ae4a7d in clone () from /lib64/libc.so.6
(gdb)
感谢您的光临!
-
Python期望在尝试从子线程回调之前,主线程进行一定数量的初始化。
如果主线程是嵌入Python的应用程序,则应
PyEval_InitThreads()
在调用后立即调用Py_Initialize()
。如果主线程是Python解释器本身(如此处所示),则使用多线程扩展模块的模块应尽早包含“导入线程”,以确保
PyEval_InitThreads()
在产生任何子线程之前可以正确调用该线程。
-
python跟踪分段错误
2021-01-29 关注 0 浏览97 1答案
-
确定导致分段错误的代码行?
2022-07-28 关注 0 浏览12 1答案
-
如何调试Python分段错误?
2021-01-29 关注 0 浏览66 1答案
-
您如何从C代码调用Python代码?
2021-01-29 关注 0 浏览115 1答案
-
将Python嵌入C ++并使用Boost.Python从C ++代码调用方法
2021-01-29 关注 0 浏览116 1答案
-
运行两个命令时,Python崩溃(分段错误:11)
2021-01-29 关注 0 浏览44 1答案
-
从PHP调用Python并获取返回代码
2021-01-29 关注 0 浏览86 1答案
-
通过cython从c调用python代码
2021-01-29 关注 0 浏览87 1答案
-
从C#调用python代码(.py文件)
2021-01-29 关注 0 浏览111 1答案
-
Python从函数返回时挂断
2021-01-29 关注 0 浏览58 1答案