C++中如何停止线程的执行
How to stop the thread execution in 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;
}
问题不在于 join
,它(顺便说一句)并不意味着用于停止或终止线程。
您的线程正在执行的函数包含一个永远不会终止的 while(true)
,因为它只能休眠和解锁锁,没有别的。
这意味着 bReading.store
将永远不会被调用,因此在主线程循环中您将始终通过 is
的这个分支
if (bReading.load())
continue;
意味着 main
也将永远执行。
std::join
用于从一个线程等待另一个线程完成它的工作。当您从 main
线程执行 thread1.join()
时,main
将 等待 直到 thread1
完成其执行,然后再执行任何其他说明。
我不知道停止 thread
的内置可能性。由于您的线程中嵌入了 endless-loop
,它不会随时停止。
std::thread::join
不会终止您的线程。当你需要它时,你必须实现一些东西来结束你的循环。
- 一个
bool
变量,您在 thread
必须退出时设置 false
。例如while(run)
或类似的东西;为简单起见,您还可以使用 std::atomic<bool>
- 您检查的信号变量。
std::condition_variable
你现在所做的是,你在你的 main-thread
中等待你的 thread
终止。由于 std::thread::join
不会终止您的 thread
,因此您的 main-thread
将永远执行。
注意:当您选择实施 bool
解决方案时。你应该用 mutex
或类似的东西保护这个 bool
。
感谢您的评论。因为我不想将每个人都指向 boost
,但你提到了它。查找信息 here.
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()
.
我在主程序中创建了一个线程,一旦主程序终止,线程执行就必须停止。我正在使用 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;
}
问题不在于 join
,它(顺便说一句)并不意味着用于停止或终止线程。
您的线程正在执行的函数包含一个永远不会终止的 while(true)
,因为它只能休眠和解锁锁,没有别的。
这意味着 bReading.store
将永远不会被调用,因此在主线程循环中您将始终通过 is
if (bReading.load())
continue;
意味着 main
也将永远执行。
std::join
用于从一个线程等待另一个线程完成它的工作。当您从 main
线程执行 thread1.join()
时,main
将 等待 直到 thread1
完成其执行,然后再执行任何其他说明。
我不知道停止 thread
的内置可能性。由于您的线程中嵌入了 endless-loop
,它不会随时停止。
std::thread::join
不会终止您的线程。当你需要它时,你必须实现一些东西来结束你的循环。
- 一个
bool
变量,您在thread
必须退出时设置false
。例如while(run)
或类似的东西;为简单起见,您还可以使用std::atomic<bool>
- 您检查的信号变量。
std::condition_variable
你现在所做的是,你在你的 main-thread
中等待你的 thread
终止。由于 std::thread::join
不会终止您的 thread
,因此您的 main-thread
将永远执行。
注意:当您选择实施 bool
解决方案时。你应该用 mutex
或类似的东西保护这个 bool
。
感谢您的评论。因为我不想将每个人都指向 boost
,但你提到了它。查找信息 here.
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()
.