提问者:小点点

如何在C++中停止线程执行


我在主程序中创建了一个线程,一旦主程序终止,线程的执行就必须停止。 我正在使用reader.join();终止线程执行。 但它并没有停止执行。

我尝试使用下面提到的代码,我正在使用thread.join();函数,但是它无法终止线程。 在主程序之后,我的线程也继续执行。

#include <algorithm>
#include <array>
#include <atomic>
#include <mutex>
#include <queue>
#include <cstdint>
#include <thread>
#include <vector>

using namespace std;
using namespace std::chrono;

typedef pair<int, Mat> pairImage;

class PairComp {
public:
    bool operator()(const pairImage& n1, const pairImage& n2) const
    {
        if (n1.first == n2.first)
            return n1.first > n2.first;
        return n1.first > n2.first;
    }
};

int main(int argc, char* argv[])
{
    mutex mtxQueueInput;
    queue<pairImage> queueInput;
    int total = 0;
    atomic<bool> bReading(true);
    thread reader([&]() {
        int idxInputImage = 0;
        while (true) {
            Mat img = imread("img_folder/");
            mtxQueueInput.lock();
            queueInput.push(make_pair(idxInputImage++, img));
            if (queueInput.size() >= 100) {
                mtxQueueInput.unlock();
                cout << "[Warning]input queue size is " << queueInput.size();
                // Sleep for a moment
                sleep(2);
            }
            else {
                mtxQueueInput.unlock();
            }
        }
        bReading.store(false);
    });

    while (true) {
        pair<int, Mat> pairIndexImage;
        mtxQueueInput.lock();
        if (queueInput.empty()) {
            mtxQueueInput.unlock();
            if (bReading.load())
                continue;
            else
                break;
        }
        else {
            // Get an image from input queue
            pairIndexImage = queueInput.front();
            queueInput.pop();
        }
        mtxQueueInput.unlock();
        cv::Mat frame = pairIndexImage.second;

        cv::rectangle(frame, cv::Rect{ 100, 100, 100, 100 }, 0xff);
    }

    cv::imshow("out_image", frame);
    waitKey(1);

    if (total++ == 200)
        break;

    if (reader.joinable()) {
        reader.join();
    }

    return 0;
}

共3个答案

匿名用户

thread.join()不会导致线程终止,它会等待,直到线程结束。 线程的责任是结束它的执行,例如通过定期检查某个条件(如标志)。

您已经有一个atomic标志breading,它似乎会导致线程退出。

        if (queueInput.empty()) {
            mtxQueueInput.unlock();
            if (bReading.load())
                continue;
            else
                break;  // thread will exit when queue is empty and bReading == false

所以您只需要在调用thread.join()之前在外部线程中设置breading=false

bReading = false;
reader.join();

请注意,线程内的breading.store(false);将不起作用。

注意:您不需要调用atomic.load()atomic.store(),您可以在代码中使用它们,代码将隐式调用load()store()

匿名用户

我不知道停止线程的内置可能性。 由于您的线程中嵌入了一个undingle-loop,因此它不会在任何时候停止。

std::thread::join不会终止线程。 当你需要的时候,你必须实现一些东西来结束你的循环。

  • 线程必须退出时,您将设置为falsebool变量。 例如while(run)或类似的内容; 为了简单起见,您还可以使用std::atomic
  • 您要检查的信令变量。 std::condition_variable

您现在要做的是,在主线程中等待线程终止。 因为std::thread::join不会终止您的线程,所以您的主线程将永远执行。

注意:当您选择实现bool解决方案时。 您应该使用mutex或类似的东西来保护这个bool

谢谢你的评论。 因为我不想让每个人都指向boost,但是您提到了它。 在这里查找信息。

匿名用户

问题不在于join,它(btw)不是用来停止或终止线程的。

您的线程正在执行的函数包含一个while(true),该函数永远不会终止,因为它只能休眠和解锁,没有其他功能。

这意味着永远不会调用breading.store,因此在主线程循环中,您将始终使用

if (bReading.load())
        continue;

这也意味着main将永远执行。

std::join用于从一个线程等待另一个线程完成其工作。 当您从main线程执行thread1.join()时,会发生的情况是main将等到thread1完成执行后再执行任何其他指令。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(何在|c++|中|停止|线程|执行)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?