Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Hvzh от Декабрь 01, 2016, 00:41



Название: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 01, 2016, 00:41
Доброго времени суток!

По роду своей деятельности я практически не сталкивался с разработкой многопоточных приложений, но теперь пришлось. Задача следующая. Пишу программу, которая занимается обработкой видеопотока в режиме реального времени. Первая часть программы представляет собой Web-сервер (за основу взял QtWebApp), вторая - модуль обработки видеопотока. Удаленный клиет шлет на Веб-сервер запросы типа начать обработку видеопотока, закончить обработку видеопотока, получить текущие данные по обработке. Я хотел сделать так, чтобы при получении запроса на начало обработки запускался бы модуль обработки в отдельном потоке и работал бы до получения сигнала об окончании или при окончании видеопотока. Не могу понять, как это можно реализовать по уму.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: qate от Декабрь 01, 2016, 09:10
почитать для ознакомления https://wiki.qt.io/Threads_Events_QObjects, можно еще "Энтони Уильямс - Параллельное программирование на С++ в действии"

пришли данные на обработку - кинуть их событием в поток
пришел сброс - кинуть событие в поток
поток завершил работу - событие об окончании



Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 11:38
В общем, где-то я с потоками таки накосячил. Как у меня сейчас все устроено. Запуск http-сервера:

Код:
int main(int argc, char *argv[])
{
//    qInstallMessageHandler(myMessageOutput);

    QCoreApplication app(argc, argv);

    // Load the configuration file
    QString configFileName=searchConfigFile();
    QSettings* listenerSettings=new QSettings(configFileName, QSettings::IniFormat, &app);

    listenerSettings->beginGroup("listener");

    // Start the HTTP server
    new HttpListener(listenerSettings, new RequestMapper(&app), &app);
    return app.exec();
}

Вот код маппера запросов:
Код:
void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
    QByteArray path=request.getPath();
    qDebug("RequestMapper: path=%s",path.data());

    if (path=="/stop")
    {
        StopController().service(request, response);
    }
    else if (path=="/start")
    {
        StartController().service(request, response);
    }
    else if(path=="/data")
    {
        DataController().service(request, response);
    }
    else
    {
        response.setStatus(404,"Not found");
        response.write("The URL is wrong, no such document.",true);
    }

    qDebug("RequestMapper: finished request");
}
Сервер получает запрос start на присоединение к видеопотоку. Я делаю следующее:
Код:
void StartController::service(HttpRequest &request, HttpResponse &response) {
    QJsonObject json;

    cameraID = 0;
    newCameraID = 0;

    QByteArray url = request.getParameter("url");
    QByteArray minArea = request.getParameter("minArea");
    QByteArray maxArea = request.getParameter("maxArea");
    QByteArray startx = request.getParameter("x0");
    QByteArray starty = request.getParameter("y0");
    QByteArray endx = request.getParameter("x1");
    QByteArray endy = request.getParameter("y1");

    dbthread = new QThread;
    impthread = new QThread;

    worker = new DbWriteWorker();
    worker->setInterval(60);
    worker->moveToThread(dbthread);

    impworker = new ImageProcessingWorker(0, QString::fromUtf8(startx).toInt(), QString::fromUtf8(starty).toInt(),
                                          QString::fromUtf8(endx).toInt(), QString::fromUtf8(endy).toInt(),
                                          QString::fromUtf8(minArea).toInt(), QString::fromUtf8(maxArea).toInt(), 1, QString::fromUtf8(url));
    impworker->moveToThread(impthread);
    // Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы.
    connect(dbthread, SIGNAL(started()), worker, SLOT(process()));
    connect(impthread, SIGNAL(started()), impworker, SLOT(process()));

    // По завершению выходим из потока, и удаляем рабочий класс
    connect(worker, SIGNAL(finished()), dbthread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(impworker, SIGNAL(finished()), impthread, SLOT(quit()));
    connect(impworker, SIGNAL(finished()), impworker, SLOT(deleteLater()));

    // Удаляем поток, после выполнения операции
    connect(dbthread, SIGNAL(finished()), dbthread, SLOT(deleteLater()));
    connect(impthread, SIGNAL(finished()), impthread, SLOT(deleteLater()));
    connect(impworker, SIGNAL(sendCounters(int,int, int)), worker, SLOT(waitForDB(int,int,int)));

    connect(worker, SIGNAL(getDataSignal()), impworker, SLOT(prepareCounters()));

    dbthread->start();
    impthread->start();

Оба потока нормально стартуют и работают, НО возникает ОЧЕНЬ большая проблема. Когда worker посылает сигнал getDataSignal, то impworker его не ловит и, соответственно, не может переслать данные в worker. Я подозреваю, что это связано с тем, что потоки создаются внутри StartController::service(HttpRequest &request, HttpResponse &response), но как выйти из этого положения я не представляю...


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 11:44
В дебаг ничего не выдает? А impworker чем занят все время? Может, он просто не дает прокрутиться очереди событий?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 11:46
В дебаг ничего не выдает? А impworker чем занят все время? Может, он просто не дает прокрутиться очереди событий?
Об этом я не подумал... impworker в это время занимается в цикле чтением и обработкой видеопотока. Может, он и тормозит очередь. А можно ли это как-то подталкивать периодически?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 11:53
Наверное, у него просто некорректное чтение или обработка. Если читаются данные из файла через сигнал readyRead, то сигналы будут приходить. Надо код посмотреть, чтобы понять.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 11:55
Вот основной цикл impworker:

Код:
    while(1)
    {

        isRead = capture.read(imgFrame2);

        blobProcess(imgFrame1, imgFrame2, frameCount);

        imgFrame2Copy = imgFrame2.clone();          // get another copy of frame 2 since we changed the previous frame 2 copy in the processing above

        drawBlobInfoOnImage(blobs, imgFrame2Copy);

        bool blnAtLeastOneBlobCrossedTheLine = checkIfBlobsCrossedTheLine(blobs);

        if (blnAtLeastOneBlobCrossedTheLine == true) {
            cv::line(imgFrame2Copy, crossingLine[0], crossingLine[1], SCALAR_GREEN, 2);
        }
        else {
            cv::line(imgFrame2Copy, crossingLine[0], crossingLine[1], SCALAR_RED, 2);
        }

        drawCarCountOnImage(countAB, countBA, imgFrame2Copy);

        if(isDebug)
            cv::imshow("imgFrame2Copy", imgFrame2Copy);
        writer.write(imgFrame2Copy);

        imgFrame1 = imgFrame2.clone();           // move frame 1 up to where frame 2 is

        capture.read(imgFrame2);

        blobsPrev.clear();

        for(int i = 0; i < blobs.size(); i++)
          blobsPrev.push_back(blobs[i]);


        blnFirstFrame = false;
        frameCount++;
        if(procToKill == cameraID)
            break;
        QThread::msleep(80);
    }

capture читает фреймы из rtmp-потока.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 11:57
Собственно, как я и предполагал - очередь событий тут не проталкивается. Почему бы тебе из этого класса не кидать сигнал с картинкой?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 12:01
Собственно, как я и предполагал - очередь событий тут не проталкивается. Почему бы тебе из этого класса не кидать сигнал с картинкой?
Ты имеешь ввиду не писать тут в файл, а в каком-нибудь другом потоке?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 12:04
Нет, я имею ввиду не кидать сигнал getDataSignal из вокера, пусть вокер ждет сигналов от impworker


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 12:06
Нет, я имею ввиду не кидать сигнал getDataSignal из вокера, пусть вокер ждет сигналов от impworker
В принципе, можно попробовать по таймеру кидать... Сейчас попробую...


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 12:10
Зачем по таймеру? Получил/обработал/кинул.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 12:26
Зачем по таймеру? Получил/обработал/кинул.
Там какая фигня. На изображении подсчитываются объекты, количество которых Worker записывает в базу данных. Если посылать сигнал после каждого найденного объекта, то тормоза будут. Но, тем не менее, с таймером тоже не покатило. Сделал так:

Код:
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(prepareCounters()));
    timer->start(5000);

Код слота:

Код:
void ImageProcessingWorker::prepareCounters()
{
    qDebug() << "ImageProcessingWorker::prepareCounters send counters";
    emit sendCounters(cameraID, countAB, countBA);
}

В итоге worker получает все накопившиеся сигналы только после остановки потока impworker


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 12:35
Опять ты неверно мыслишь. :) У тебя таймер не будет срабатывать, ибо нет обработки очереди сообщений. Тебе нужно явно кидать сигнал внутри while.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 12:44
Опять ты неверно мыслишь. :) У тебя таймер не будет срабатывать, ибо нет обработки очереди сообщений. Тебе нужно явно кидать сигнал внутри while.
QCoreApplication::instance()->processEvents() внутри while спасло отца русской демократии  ;D


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 12:54
Опять ты неверно мыслишь. :) У тебя таймер не будет срабатывать, ибо нет обработки очереди сообщений. Тебе нужно явно кидать сигнал внутри while.
QCoreApplication::instance()->processEvents() внутри while спасло отца русской демократии  ;D
Это плохой ход, поэтому я тебе и не говорил про него.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 13:43
Опять ты неверно мыслишь. :) У тебя таймер не будет срабатывать, ибо нет обработки очереди сообщений. Тебе нужно явно кидать сигнал внутри while.
QCoreApplication::instance()->processEvents() внутри while спасло отца русской демократии  ;D
Это плохой ход, поэтому я тебе и не говорил про него.
Хорошо, можешь пример набросать, как мне раз в минуту данные отправлять?


Название: Re: Вопрос ламера о реализации многопоточно&#
Отправлено: Пантер от Декабрь 09, 2016, 13:48
Псевдокот.

Код
C++ (Qt)
QTime time;
time.start();
while (1) {
 //some
 if (time.esapsed () > ???) {
   emit newDataAvailable();
   time.start();
}
}
 


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 09, 2016, 14:04
Ok, сейчас попробую


Название: Re: Вопрос ламера о реализации многопоточно&#
Отправлено: Hvzh от Декабрь 09, 2016, 14:13
Псевдокот.

Код
C++ (Qt)
QTime time;
time.start();
while (1) {
 //some
 if (time.esapsed () > ???) {
   emit newDataAvailable();
   time.start();
}
}
 
Спасибо, работает. Правда, в if заменил time.start на time.restart


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 14:33
Это был псевдокот, писал по памяти. :)


Название: Re: Вопрос ламера о реализации многопоточно&#
Отправлено: Igors от Декабрь 09, 2016, 15:02
Псевдокот.

Код
C++ (Qt)
QTime time;
time.start();
while (1) {
 //some
 if (time.esapsed () > ???) {
   emit newDataAvailable();
   time.start();
}
}
 
Цитировать
Уж больно ты щедрый, председатель, на колхозное добро
(классика советского кино)


Название: Re: Вопрос ламера о реализации многопоточно&#
Отправлено: Авварон от Декабрь 09, 2016, 15:20
Псевдокот.

А что не QTimer?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 15:22
Вот докопались, я вообще в данный момент на пыхе пишу.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Авварон от Декабрь 09, 2016, 15:37
Оно и видно ;D


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 09, 2016, 15:38
Не надо смеяться над вынужнденным пыхером. :(


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 12:53
Еще раз прошу помощи! Опять возникла проблема с сигналами. Я создаю потоки следующим образом:

Код:
    dbthread = new QThread;
    impthread = new QThread;

    worker = new DbWriteWorker();
    worker->setInterval(60);

    impworker = new ImageProcessingWorker(0, QString::fromUtf8(startx).toInt(), QString::fromUtf8(starty).toInt(),
                                          QString::fromUtf8(endx).toInt(), QString::fromUtf8(endy).toInt(),
                                          QString::fromUtf8(minArea).toInt(), QString::fromUtf8(maxArea).toInt(), 1, QString::fromUtf8(url));
    // Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы.
    connect(dbthread, SIGNAL(started()), worker, SLOT(process()));
    connect(impthread, SIGNAL(started()), impworker, SLOT(process()));

    // По завершению выходим из потока, и удаляем рабочий класс
    connect(worker, SIGNAL(finished()), dbthread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(impworker, SIGNAL(finished()), impthread, SLOT(quit()));
    connect(impworker, SIGNAL(finished()), impworker, SLOT(deleteLater()));

    // Удаляем поток, после выполнения операции
    connect(dbthread, SIGNAL(finished()), dbthread, SLOT(deleteLater()));
    connect(impthread, SIGNAL(finished()), impthread, SLOT(deleteLater()));
    connect(impworker, SIGNAL(sendCounters(int,int, int)), worker, SLOT(waitForDB(int,int,int)));
    connect(impworker, SIGNAL(newCameraOpened(int)), this, SLOT(cameraStarted(int)));

    //connect(worker, SIGNAL(getDataSignal()), impworker, SLOT(prepareCounters()));

    worker->moveToThread(dbthread);
    impworker->moveToThread(impthread);
    dbthread->start();
    impthread->start();

Строка
Код:
 connect(impworker, SIGNAL(newCameraOpened(int)), this, SLOT(cameraStarted(int)));
служит для получения ID видеопотока, чтобы использовать его для запроса данных из базы, а также для его закрытия.

В потоке посылается сигнал:
Код:
void ImageProcessingWorker::process()
{

    qDebug() << "ImageProcessingWorker::process source = " << strSource;

    bool isRead = 0;
    cv::Mat imgFrame1;
    cv::Mat imgFrame2;
    cv::Mat imgFrame2Copy;

    blnFirstFrame = true;

    int frameCount = 2;
    try
    {
        capture.open(strSource.toStdString().c_str());
    }
    catch(cv::Exception& e)
    {
        std::cerr << "Exception was catched!" << std::endl;
        cameraID = -1;
        emit newCameraOpened(cameraID);
        return;
    }

    if(!capture.isOpened()){
      std::cerr << "Cannot open camera!" << std::endl;
      cameraID = -1;
      emit newCameraOpened(cameraID);
      return;
    }
    else
    {
        isRead = capture.read(imgFrame1);
        imageSize.height = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
        imageSize.width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
        fps = 25;

        cameraID = createNewDbLine();
        emit newCameraOpened(cameraID);
        if(cameraID == -1)
            return;

        QString fName = QString::number(cameraID) + ".avi";
        if(!writer.open(fName.toStdString().c_str(), CV_FOURCC('F', 'M', 'P', '4'), fps, imageSize))
        {
            std::cerr << "Cannot write video!" << std::endl;
            capture.release();
            cameraID = -1;
            return;
        }
    }
,
однако в пункт назначения сигнал не приходит. И вообще непонятно, уходит ли...


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 13:17
Добавь вывод qDebug ()  в месте выдачи сигнала и в слоте.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 13:25
В слоте есть, также qDebug есть в createNewDbLine, то есть, перед сигналом. В слоте ничего не выводится, с createNewDbLine все нормально


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 13:37
Есть варианты:
1. У тебя источник и приемник получаются в одном потоке и этот поток занят.
2. Поток приемника занят.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 13:44
Думаю, скорее второе... Буду проверять. Сейчас у меня вот так. После старта потоков  начинается ожидание ответа от потока, оформленное в виде бесконечного цикла:

Код:
    for(;;)
    {
        if(сameraID == 0)
            continue;
        else
        {
            std::cout << "StartController::service new camera ID = " << cameraID << std::endl ;
            break;
        }
    }

Значение cameraID должно менятся в слоте, который выглядит вот так:
Код:
void StartController::cameraStarted(int id)
{
    cameraID = id;
    qDebug() << "StartController::cameraStarted: cameraID = " << cameraID;
}
Может, вся проблема из-за цикла?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 13:55
Блин, конечно из-за цикла. Зачем тебе цикл нужен?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 14:01
Вот полная функция:

Код:
void StartController::service(HttpRequest &request, HttpResponse &response) {
    QJsonObject json;

    cameraID = 0;
    newCameraID = 0;

    QByteArray url = request.getParameter("url");
    QByteArray minArea = request.getParameter("minArea");
    QByteArray maxArea = request.getParameter("maxArea");
    QByteArray startx = request.getParameter("x0");
    QByteArray starty = request.getParameter("y0");
    QByteArray endx = request.getParameter("x1");
    QByteArray endy = request.getParameter("y1");

    dbthread = new QThread;
    impthread = new QThread;

    worker = new DbWriteWorker();
    worker->setInterval(60);
    worker->moveToThread(dbthread);

    impworker = new ImageProcessingWorker(0, QString::fromUtf8(startx).toInt(), QString::fromUtf8(starty).toInt(),
                                          QString::fromUtf8(endx).toInt(), QString::fromUtf8(endy).toInt(),
                                          QString::fromUtf8(minArea).toInt(), QString::fromUtf8(maxArea).toInt(), 1, QString::fromUtf8(url));
    impworker->moveToThread(impthread);
    // Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы.
    connect(dbthread, SIGNAL(started()), worker, SLOT(process()));
    connect(impthread, SIGNAL(started()), impworker, SLOT(process()));

    // По завершению выходим из потока, и удаляем рабочий класс
    connect(worker, SIGNAL(finished()), dbthread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(impworker, SIGNAL(finished()), impthread, SLOT(quit()));
    connect(impworker, SIGNAL(finished()), impworker, SLOT(deleteLater()));

    // Удаляем поток, после выполнения операции
    connect(dbthread, SIGNAL(finished()), dbthread, SLOT(deleteLater()));
    connect(impthread, SIGNAL(finished()), impthread, SLOT(deleteLater()));
    connect(impworker, SIGNAL(sendCounters(int,int, int)), worker, SLOT(waitForDB(int,int,int)));

    //connect(worker, SIGNAL(getDataSignal()), impworker, SLOT(prepareCounters()));

    dbthread->start();
    impthread->start();

    std::cout << "Waiting for new camera connection" << std::endl ;

    for(;;)
    {
        if(сameraID == 0)
            continue;
        else
        {
            std::cout << "StartController::service new camera ID = " << cameraID << std::endl ;
            break;
        }
    }

    if(cameraID > 0)
    {
        json["result"] = "Ok";
    }
    else
    {
         json["result"] = "Error";
    }
    json["cameraID"] = cameraID;

    QJsonDocument saveDoc(json);
    response.write(saveDoc.toJson(),true);
}


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 14:06
Код
C++ (Qt)
connect(impworker, SIGNAL(newCameraOpened(int)), this, SLOT(cameraStarted(int)));
 
QEventLoop eventLoop;
connect(impworker, SIGNAL(newCameraOpened(int)), &eventLoop, SLOT(quit()));
eventLoop.exec();
 
//Here we know cameraId
 


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 14:08
Если у тебя Qt5 и 11 стандарт, лучше лямбду вместо слота заюзать.

Код
C++ (Qt)
connect(impworker, SIGNAL(newCameraOpened(int)), [&eventLoop, &cameraId] (int id) {cameraId = id; eventLoop.quit();});
 


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 14:14
Сейчас попробую...


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 14:26
Ура, работает. Еще одно огромное спасибо!


Название: Re: Вопрос ламера о реализации многопоточно&#
Отправлено: Hvzh от Декабрь 14, 2016, 14:38
Ну, и до кучи еще один вопрос. Есть функция отключения камеры, которая принимает оь браузера один параметр - ID камеры. Сейчас она выглядит так:

Код:
void StopController::service(HttpRequest &request, HttpResponse &response) {
    QJsonObject json;

    camSatus = -1;

    QByteArray par = request.getParameter("id");

    qDebug() << "StopController::ID int = " << par.toInt();

    procToKill = par.toInt();

    for(;;)
    {
        if(procToKill == 0)
            break;
    }

     json["result"] = "Ok";
     json["value"] = par.toInt();

        QJsonDocument saveDoc(json);
    response.write(saveDoc.toJson(),true);
}

Остановка сейчас сделана через глобальную переменную procToKill. Это работает, но вариант совершенно неподходящий при большом количестве подключений. При этом функция о процессах ничего, кроме переданного ID не знает. Я могу послать сигнал, например, stopCamera(cameraID), но как мне ответ поймать? И как заставить impworker этот сигнал ловить?


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 14:50
У тебя каждая камера это отдельный процесс? Храни мапу соответствия номера камеры и номера процесса. Или я тчо-то не так понял.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 14:59
Каждая камера - отдельный поток


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 15:01
Храни где-нибудь мапу соответствия.


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 15:11
Храни где-нибудь мапу соответствия.
Ну, могу я получить ИД потока, но он же, вроде, для внутреннего пользования, и остановить поток используя Thread ID вроде нельзя


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 15:22
QMap<int, QThread*> threads;


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Пантер от Декабрь 14, 2016, 15:23
А еще лучше:

QMap<int, YouClass*> m;
m->stop();


Название: Re: Вопрос ламера о реализации многопоточности
Отправлено: Hvzh от Декабрь 14, 2016, 18:21
А еще лучше:

QMap<int, YouClass*> m;
m->stop();
Сделал так. Работает. Еще раз огромное спасибо!