Я создал оболочку C++
для доступа к моим Python
модулям. все работает, пока я не попытаюсь использовать потоки в моем приложении.
На моем модуле Python
есть метод, который читает с веб-камеры (поэтому он использует бесконечное число l oop), и я посылаю обратные вызовы с C++
чтобы получить изображение и другую необходимую информацию из него.
Так как у нас есть метод блокировки, я решил использовать потоки.
Потоки в части Python
, кажется, не работают на стороне C++
, которая если я вызываю асин c часть счетчика webcam_feed
l oop, ни один из моих обратных вызовов фактически не выполняется (на части python все подпрограммы выполняются, однако, кажется, что это не доходит до C ++ как-то в разделе. Я не получаю никакой обратной связи на стороне C ++, однако в части Python эти подпрограммы, отвечающие за выполнение обратных вызовов, сохраняют информацию на диск, поэтому я точно знаю, что они выполняются).
Я спросил отдельный вопрос для него здесь .
Поэтому я решил использовать многопоточность внутри клиента C ++. Однако всякий раз, когда я выполняю код (приведенный ниже), я получаю нарушение прав доступа всякий раз, когда я хочу использовать какие-либо методы после запуска потока. Вот примеры обратных вызовов, которые у меня есть на данный момент:
void default_callback(bool status, std::string id, py::array_t<uint8_t>& img)
{
auto rows = img.shape(0);
auto cols = img.shape(1);
auto type = CV_8UC3;
cv::Mat img1(rows, cols, type, img.mutable_data());
cv::imshow("from callback", img1);
cv::waitKey(1);
auto timenow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::cout << "\narg1: " << status << " arg2: " << id << " arg3: " << typeid(img).name() << " " << ctime(&timenow) << std::endl;
}
void default_c_callback_temporary(bool status, char* message)
{
std::cout << "status is: " << status << " id/name: " << message << " ptr:" << "" << std::endl;
std::ofstream myfile;
myfile.open("example.txt");
myfile << "Writing this to a file: " << status << message << std::endl;
myfile.close();
}
И это фактический тест
void thread_test_start(Core* core)
{
try
{
core->SetCpuAffinity(2);
core->AddCallback(default_callback);
core->AddCallback_C_tmp(default_c_callback_temporary);
//set true to run the async version (implemented in python)
core->Start(false);
}
catch (const std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
}
int main()
{
Core* core = new Core(false);
std::thread t(thread_test_start, core);
py::print(core->GetCallbacks());
std::cout << "\nGet C Callbacks:\n";
py::print(core->GetCallbacks_C_tmp());
std::cout << "\nEverything done. press Enter to Exit";
t.join();
std::getchar();
return 0;
}
Вызов core->GetCallbacks()
вызывает нарушение доступа к памяти:
Exception thrown at 0x000000006FCC6D80 (python36.dll) in TestDLL.exe: 0xC0000005: Access violation reading location 0x0000000000000010.
А вот снимок, показывающий ошибку нарушения доступа внутри VS2019:
То же самое происходит и так:
void thread_test_start2()
{
try
{
Core* core = new Core(false);
core->SetCpuAffinity(2);
core->AddCallback(default_callback);
core->AddCallback_C_tmp(default_c_callback_temporary);
std::thread t(&Core::Start, core, false);
py::print(core->GetCallbacks());
std::cout << "\nGet C Callbacks:\n";
py::print(core->GetCallbacks_C_tmp());
t.join();
}
catch (const std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
}
Результат:
Exception thrown at 0x000000006FCC0CDF (python36.dll) in TestDLL.exe: 0xC0000005: Access violation writing location 0x0000000000000020.
, как и предыдущий. Почему я получаю эту ошибку? Разве мы не можем использовать потоки с Pybind11? Что мне здесь не хватает?
Вот пример проекта для воссоздания этой проблемы: https://workupload.com/file/6LmfRtbztHK