0

我只是在 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)

电流输出

总是 1234

所需输出

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

1 回答 1

0

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

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

所以你需要做的是Vehiclestd::mutex. 在每个 getter 和每个 setter 中,你锁定和解锁这个互斥锁。这很容易std::scoped_lock- 这将在方法返回时自动解锁互斥锁。

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

于 2021-11-29T11:11:01.837 回答