问题
I created one thread in my main program, thread execution has to stop once the main program will terminate. I am using reader.join();
to terminate the thread execution. But it is not stopping the execution.
I tried with below-mentioned code, I am using thread.join();
function, but it is failed to terminate a thread. And after the main program also my thread is kept executing.
#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;
}
回答1:
thread.join()
does not cause the thread to terminate, it waits until the thread ends. It's the responsibility of the thread to end its execution, for example by periodically checking for a certain condition, like a flag.
You already have an atomic
flag bReading
, which appears to cause the thread to exit.
if (queueInput.empty()) {
mtxQueueInput.unlock();
if (bReading.load())
continue;
else
break; // thread will exit when queue is empty and bReading == false
So all you need is to set bReading = false
in the outer thread before calling thread.join()
.
bReading = false;
reader.join();
Note that bReading.store(false);
inside your thread will have no effect.
Note: you don't need to call atomic.load()
and atomic.store()
, you can just use them in your code, which will call load()
and store()
implicitly.
回答2:
I'm not aware of an built in possibility to stop a thread
. Since you have a endless-loop
embedded in your thread, it won't stop at any time.
std::thread::join
does not terminate your thread. You have to implement something to end your loop, when you demand it.
- A
bool
variable you setfalse
when thethread
has to exit. e.g.while(run)
or something like that; for simplicity you could also use astd::atomic<bool>
- A signaling variable you check.
std::condition_variable
What you do at the moment is, you wait in your main-thread
that your thread
terminates. Since std::thread::join
does't terminate your thread
, your main-thread
will execute forever.
NOTE: When you choose to implement the bool
solution. You should protect this bool
with an mutex
or something alike.
Thanks for the comment. As I don't want to point everyone to boost
, but you mentioned it. Find information here.
回答3:
The problem is not with join
which (btw) is not meant to be used to stop or terminate a thread.
The function that your thread is executing contains a while(true)
which will never terminate, because it can only sleep and unlock the lock, nothing else.
This means that bReading.store
will never be called and as a consequence in the main thread loop you will always go though this branch of the is
if (bReading.load())
continue;
meaning that also the main
will execute forever.
std::join
is used to wait from a thread that another thread has completed its work. when you do thread1.join()
from the main
thread what happens is that main
will wait until thread1
has completed its execution before executing any other instruction.
来源:https://stackoverflow.com/questions/55824719/how-to-stop-the-thread-execution-in-c