使用Python和C API进行多线程 [英] Multithreading with Python and C api

查看:305
本文介绍了使用Python和C API进行多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用C api来使用我的Python库的C ++程序. Python库和C ++代码都是多线程的.

I have a C++ program that uses the C api to use a Python library of mine. Both the Python library AND the C++ code are multithreaded.

尤其是,C ++程序的一个线程实例化了一个从threading.Thread继承的Python对象.我需要我所有的C ++线程都能够在该对象上调用方法.

In particular, one thread of the C++ program instantiates a Python object that inherits from threading.Thread. I need all my C++ threads to be able to call methods on that object.

从我的第一次尝试开始(我只是从主线程实例化该对象,然后等待一段时间,然后调用该方法),我注意到与刚创建的对象相关联的Python线程的执行会在执行返回到C ++程序.

From my very first tries (I naively just instantiate the object from the main thread, then wait some time, then call the method) I noticed that the execution of the Python thread associated with the object just created stops as soon as the execution comes back to the C++ program.

如果执行停留在Python上(例如,如果我调用PyRun_SimpleString("time.sleep(5)");),则Python线程的执行在后台继续,并且一切正常,直到等待结束,然后执行返回C ++.

If the execution stays with Python (for example, if I call PyRun_SimpleString("time.sleep(5)");) the execution of the Python thread continues in background and everything works fine until the wait ends and the execution goes back to C++.

我显然做错了事.我该怎么做才能使我的C ++和Python成为多线程并且能够很好地相互配合?我以前没有该领域的经验,所以请不要承担任何责任!

I am evidently doing something wrong. What should I do to make both my C++ and Python multithreaded and capable of working with each other nicely? I have no previous experience in the field so please don't assume anything!

推荐答案

执行您要执行的操作的正确步骤顺序是:

A correct order of steps to perform what you are trying to do is:

  • 在主线程中:

  • In the main thread:

  1. 使用Py_Initialize*初始化Python.
  2. 使用PyEval_InitThreads()初始化Python线程支持.
  3. 启动C ++线程.
  1. Initialize Python using Py_Initialize*.
  2. Initialize Python threading support using PyEval_InitThreads().
  3. Start the C++ thread.

这时,主线程仍然保留GIL.

At this point, the main thread still holds the GIL.

  • 在C ++线程中:
  • In a C++ thread:
  1. 使用PyGILState_Ensure()获取GIL.
  2. 创建一个新的Python线程对象并启动它.
  3. 使用PyGILState_Release()释放GIL.
  4. 睡眠,执行一些有用的操作或退出线程.
  1. Acquire the GIL using PyGILState_Ensure().
  2. Create a new Python thread object and start it.
  3. Release the GIL using PyGILState_Release().
  4. Sleep, do something useful or exit the thread.

由于主线程持有GIL,因此该线程将等待获取GIL.如果主线程调用Python API,则它可能会不时释放GIL,从而允许Python线程执行一会儿.

Because the main thread holds the GIL, this thread will be waiting to acquire the GIL. If the main thread calls the Python API it may release the GIL from time to time allowing the Python thread to execute for a little while.

  • 返回主线程:
  • Back in the main thread:
  1. 释放GIL,使线程可以使用PyEval_SaveThread()
  2. 运行
  3. 在尝试使用其他Python调用之前,请使用PyEval_RestoreThread()
  4. 重新获取GIL.
  1. Release the GIL, enabling threads to run using PyEval_SaveThread()
  2. Before attempting to use other Python calls, reacquire the GIL using PyEval_RestoreThread()

我怀疑您缺少最后一步-在主线程中释放GIL,从而允许Python线程执行.

I suspect that you are missing the last step - releasing the GIL in the main thread, allowing the Python thread to execute.

我有一个小而完整的示例,它完全可以在此链接中进行操作.

I have a small but complete example that does exactly that at this link.

这篇关于使用Python和C API进行多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆