繁体   English   中英

PYBIND11:当 Z23EEEB4347BDD26BDDFC6B7EE9A3B75 嵌入另一个线程并在另一个线程中运行时,在另一个 c++ 线程中更改 class object 值

[英]PYBIND11: Make changes to class object value in another c++ thread when python interpreter is embedded and running in another thread

我只是在 python 中打印 car1.vehicle_id 的值。 我希望它在前 2 秒打印“1234”,然后当另一个线程中的值更改为“4543”时,更改应该在 python 中生效。 这是可能的还是有一个简单的例子可以帮助我解决这个问题?

c++

 #include <pybind11/embed.h> #include <string> #include <thread> #include <chrono> // Define namespace for pybind11 namespace py = pybind11; class Vehiclee { // Access specifier public: Vehiclee(){}; ~Vehiclee() {} // Data Members int vehicle_id; std::string vehicle_name; std::string vehicle_color; // Member Functions() void printname() { std::cout << "Vehicle id is: " << vehicle_id; std::cout << "Vehicle name is: " << vehicle_name; std::cout << "Vehicle color is: " << vehicle_color; } }; PYBIND11_EMBEDDED_MODULE(embeded, m){ py::class_(m, "Vehiclee").def_readonly("vehicle_name", &Vehiclee::vehicle_name).def_readonly("vehicle_color", &Vehiclee::vehicle_color).def_readonly("vehicle_id", &Vehiclee::vehicle_id); } py::scoped_interpreter python{}; Vehiclee car1; void threadFunc() { sleep(2); std::cout<<"entering thread"; car1.vehicle_id = 4543; std::cout<<"Modified val in thread"; } int main() { // Initialize the python interpreter // Import all the functions from scripts by file name in the working directory auto simpleFuncs = py::module::import("simpleFuncs"); // Test if C++ objects can be passed into python functions car1.vehicle_id = 1234; std::thread t1(threadFunc); simpleFuncs.attr("simplePrint")(car1); t1.join(); return 0; }

python

>  import time 
>  import importlib 
>  import embeded
>      
>     def simplePrint(argument): 
>           while(1): 
>               importlib.reload(embeded)
>               print(argument.vehicle_id) time.sleep(1)

当前 output

总是 1234

需要 output

1234 (for first 2 secs)
4543 (after 2 secs)

您需要了解线程的 C++ 规则。 在 C++ 中,线程可以比 Python 更好地并行运行。 这是因为在 C++ 中,线程默认情况下是完全独立运行的,而 Python 使用全局解释器锁,这会导致大量线程同步。

因此,在这种情况下,您确实需要线程同步,因为线程共享一个变量( car1 )。 挑战在于.def_readonly隐藏了一些不进行同步的样板代码 - 这是有道理的,因为它应该使用什么 object 来同步?

所以你需要做的是在Vehicle中创建 getter 和 setter 方法,并添加一个std::mutex 在每个 getter 和每个 setter 中,你锁定和解锁这个互斥锁。 使用std::scoped_lock很容易 - 这将在方法返回时自动解锁互斥锁。

还有其他选择。 对于vehicle_id你可以使用std::atomic_int ,但你可能仍然需要一个 getter 方法。 我不认为 pybind 理解原子变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM