这两天我一直在研究这个问题。因为项目的需求,需要在python中写一个线程,并且需要用C++调用起来。
刚开始,我以为和平常C++调用python的方式是一样的。
结果是:
python的接口函数可以被保存成功,但是里面的线程根本不会调用。
起初,我还以为是我的接口写的有的问题,查找了也没发现有问题。
而后,我又认为是python中的线程写的有问题。可是我又想,python中写的线程我可以自己调用成功,为什么到了C++调用的时候就不行了呢?百思不得其解。
从网上查询了很多资料,有说是需要在C++中调用python的线程接口函数,后来我就按照别的方法试了试,下面是我尝试的代码,大家可以参考下。
Py_Initialize() ;
PyEval_InitThreads() ;
pMainThreadState = PyThreadState_Get() ;
PyEval_ReleaseLock() ;
//多线程代码.....
PyGILState_Ensure() ;
Py_Finalize() ;
我不给予评论,我只想说,使用这个结构的时候,我在调用python接口时,就会出现内存冲突的错误。
后来,我就放弃了这个方法。
我的python中的代码如下所示。
在此,我不展示完整的代码段,只是用一个简单的小例子说明。这样通俗易懂,但是我保证,我写的代码可以调通。
我是一个喜欢用简单例子推到复杂过程的人,如果给我一堆特别多的代码时,我一点看的欲望都没有了。不知道大家有没有和我的想法是一样的,哈哈
import threading
import time
g_flage = 0
def thread_test():
while(True):
if g_flage == False:
print('循环代码段区域')
else:
break
'''
开启线程
'''
def Begin_voice():
print('开启线程!')
global g_flage
g_flage = False
p = threading.Thread(target=thread_test)
p.start()
'''
关闭线程
'''
def End_voice():
print('关闭线程!')
global g_flage
g_flage = True
return '-1'
if __name__ == "__main__":
Begin_voice()
time.sleep(2)
End_voice()
print('存储成功!OK')
上面是我的一个小例子。直接复制粘贴就可以运行,并且结果如下图所示:
下面,这一章的主要内容是讲解我这个简单的线程例子。
1:需要包含的头文件
在python中使用线程用到了threading这个包。
至于Thread和threading的区别,我在这里不再进行过多的解释,别人的博客比我说的好。
对于我这种半吊子转到python中的,解释也无法很好地解释,还不如不说。
使用“import time”这个包主要是因为在主函数运行时,需要让主程序等待子线程结束后再执行主程序的工作
time.sleep(2)
2:创建线程、开启线程
创建线程函数 threading.Thread
其中,参数 thread_test 代表的是启动线程要运行的哪个函数
p.start()运行该线程
3:线程中运行的函数
在这里,我需要解释下:g_flage 这个变量的作用。
从整个程序上来讲,我使用 g_flage 这个变量来控制线程的开始和结束的。
有的博友里面使用的是一个for循环来自动结束程序,我偏不,我偏要用外界来控制线程的结束,如果你说我固执,也不是不可以。我就想尝试这种新的方法
那么使用这个 g_flage 的时候,问题就来了......
问题1:为什要在导入包后,先定义一次 g_flage = 0 ,再使用时 再次 声明下这个变量呢?
其实,身为C++出身的我,一开始还不理解这是做什么的,看了global的定义之后才发现是怎么回事。
我不清楚别人是怎么记住的,我只说说我的方法。
先定义一次 g_flage 这个变量,是要告诉编译器我这个是一个全局的变量。
global g_flage
4:主函数运行
在这里,如果我不写 " time.sleep(0.05)
以上这个代码,是可以在python中调用成功的。
今天的第一节内容:展示一个简单的python线程就讲解完了。如果有交流的博友,可以发邮件给我,共同讨论。
第二节内容:C++调用python这个线程出现的问题