Member 14629414 Ответов: 1

Как я могу решить эти 2 ошибки при создании потока?


У меня есть код из программы захвата видео basler, как показано ниже, который я хочу сделать в виде потока, чтобы запустить его параллельно моей основной программе:
for (uint32_t i = 0; i < c_countOfImagesToGrab && cameras.IsGrabbing(); ++i)
{
 cameras.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
 intptr_t cameraContextValue = ptrGrabResult->GetCameraContext();
#ifdef PYLON_WIN_BUILD
 Pylon::DisplayImage(cameraContextValue, ptrGrabResult);
#endif
 cout << "Camera " << cameraContextValue << ": " << 
 cameras[cameraContextValue].GetDeviceInfo().GetModelName() << endl;
 cout << "GrabSucceeded: " << ptrGrabResult->GrabSucceeded() << endl;
 cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
 cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
 const uint8_t* pImageBuffer = (uint8_t*)ptrGrabResult->GetBuffer();
 cout << "Gray value of first pixel: " << (uint32_t)pImageBuffer[0] << endl << endl;
}

I've made a thread as below and place it in the While loop of my main program:
std::thread t1([&](uint32_t i) {
for (uint32_t i = 0; i < c_countOfImagesToGrab && cameras.IsGrabbing(); ++i)
 {
 cameras.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
 intptr_t cameraContextValue = ptrGrabResult->GetCameraContext();
#ifdef PYLON_WIN_BUILD
 Pylon::DisplayImage(cameraContextValue, ptrGrabResult);
#endif
 cout << "Camera " << cameraContextValue << ": " << 
 cameras[cameraContextValue].GetDeviceInfo().GetModelName() << endl;
 cout << "GrabSucceeded: " << ptrGrabResult->GrabSucceeded() << endl;
 cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
 cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
 const uint8_t* pImageBuffer = (uint8_t*)ptrGrabResult->GetBuffer();
 cout << "Gray value of first pixel: " << (uint32_t)pImageBuffer[0] << endl << endl;
}
 }, & ptrGrabResult);

Но при компиляции программы у меня было 2 ошибки:
С2672:'СТД::ссылаться на соответствующий перегруженной функции найден
C2893:'Не удалось специализировать шаблон функции 'неизвестный тип std::invoke(Callable &&,_Types&&...)"


Что я уже пробовал:

I've trying 2 method to create this thread. Function pointer and lambda method but it remained the same result as 2 errors happened after each time compiling

Member 14629414

Может ли кто-нибудь сказать мне, как решить эту проблему? Я застрял с этим материалом около 1 недели:((
Я вам очень благодарна!!

Shao Voon Wong

Что такое тип ptrGrabResult? Укажите этот тип в качестве лямбда-параметра, который в данный момент является uint32_t. Дайте этому параметру уникальное и значимое имя, а не i, которое используется в теле лямбды.

Member 14629414

@Shao Voon Wong я даже точно не знаю, какой параметр должен передаваться в поток
так что я не уверен, что ptrGrabResult верен или нет. Но в верхнем пути кода ptrGrabResult определяется как "CGrabResultPtr ptrGrabResult;"
Это переменная для хранения захваченного кадра с камеры.

Shao Voon Wong

Смотрите мой ответ ниже.

Member 14629414

@Shao Voon Wong большое вам спасибо, что программа может быть скомпилирована без каких-либо ошибок!!!
Но, похоже, моя основная программа не работает.Может быть потому что основная программа должна подождать
нить до тех пор, пока она не закроется?.Я хочу, чтобы 2 программы работали параллельно

Shao Voon Wong

Я обновил свой ответ ниже. Вы должны вызвать join (), чтобы узнать, что поток закончил выполнение.

Shao Voon Wong

Убедитесь, что основной поток и рабочий поток не обращаются к одному и тому же объекту одновременно, иначе это приведет к повреждению памяти и неправильному результату и приведет к сбою приложения. Вы можете защитить один и тот же объект с помощью мьютекса, чтобы избежать этого.

Member 14629414

Ладно, я понял! Я вам очень благодарна!

Member 14629414

Когда я скомпилировал его он показал мне окно ошибки отладки а также это:
(в разделе "thread.h"):
thread() noexcept{
если (присоединяемые()){
_STD завершить(); =&ГТ;
точка останова orcur в проекте 34.exe

Shao Voon Wong

Вызывали ли вы join() для объекта thread до завершения программы?

Member 14629414

Если я вызову "join ()", то ошибка исчезнет, но 2 программы не будут работать одновременно

Member 14629414

@Shao Voon Wong Oh я хочу, чтобы мой рабочий поток работал параллельно основному потоку, поэтому я буду использовать t1.detach();

Member 14629414

Но когда я использую detach (), мой рабочий поток не может компилироваться, и у него есть ошибка:(( Я не могу захватить видео

Member 14629414

@Шао сайт Вонг Эй, когда я удалить рабочий поток выходит из цикла while и отсоединить() у него нет ошибки при компиляции и программа 2 параллельно прекрасно!!!
Я не знаю, как описать мою благодарность вам, вы спасли мне жизнь!!! Я беспокоился об этой проблеме в течение недели, и теперь я исправил ее благодаря вам!!

Shao Voon Wong

Добро пожаловать. Рад быть полезным.

Не вызывая join(), как вы узнаете, что рабочий поток закончился? Обычно мы запускаем поток и делаем другие вещи в основном потоке перед вызовом join (), чтобы выполнение основного потока не блокировалось join().

Просто чтобы вы знали, что std::cout не является потокобезопасным. Если основной поток и рабочий поток вызываются std::cout одновременно, то вывод консоли может содержать тарабарщину.

Member 14629414

@Шао Вонг Сайт
В моем верхнем пути программы я определил значение для "c_countOfImagesToGrab" на 100000 . Это означает, что рабочий поток захватит 100000 кадров, а затем автоматически закроется.

1 Ответов

Рейтинг:
9

Shao Voon Wong

Снимите крышку i параметр и &ptrGrabResult

std::thread t1([&]() {
for (uint32_t i = 0; i < c_countOfImagesToGrab && cameras.IsGrabbing(); ++i)
{
    cameras.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
    intptr_t cameraContextValue = ptrGrabResult->GetCameraContext();
#ifdef PYLON_WIN_BUILD
        Pylon::DisplayImage(cameraContextValue, ptrGrabResult);
#endif
    cout << "Camera " << cameraContextValue << ": " << 
    cameras[cameraContextValue].GetDeviceInfo().GetModelName() << endl;
    cout << "GrabSucceeded: " << ptrGrabResult->GrabSucceeded() << endl;
    cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
    cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
    const uint8_t* pImageBuffer = (uint8_t*)ptrGrabResult->GetBuffer();
    cout << "Gray value of first pixel: " << (uint32_t)pImageBuffer[0] << endl << endl;
}
});

t1.join(); // have to call join() somewhere in the main thread.