我在主程序中创建了一个线程,一旦主程序终止,线程执行必须停止。我正在使用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;
}
答案 0 :(得分:4)
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
因此,您所需要做的就是在调用bReading = false
之前在外部线程中设置thread.join()
。
bReading = false;
reader.join();
请注意,线程中的bReading.store(false);
无效。
注意:您不需要调用atomic.load()
和atomic.store()
,只需在代码中使用它们即可,它们将隐式调用load()
和store()
。 / p>
答案 1 :(得分:1)
我不知道停止thread
的内置可能性。由于您的线程中嵌入了endless-loop
,因此它不会随时停止。
std::thread::join
不会终止您的线程。您必须在需要时实施一些措施来结束循环。
bool
必须退出时,您设置了false
的{{1}}变量。例如thread
或类似的东西;为简单起见,您还可以使用while(run)
std::atomic<bool>
此刻,您正在std::condition_variable
中等待main-thread
终止。由于thread
不会终止您的std::thread::join
,因此您的thread
将永远执行。
注意:当您选择实施main-thread
解决方案时。您应该使用bool
或类似的东西来保护此bool
。
感谢您的评论。因为我不想将所有人都指向mutex
,但是您提到了它。查找信息here。
答案 2 :(得分:0)
问题不是join
引起的,while(true)
并不是用来停止或终止线程的。
您的线程正在执行的函数包含一个bReading.store
,它将永远不会终止,因为它只能休眠并解锁该锁,而没有其他任何作用。
这意味着if (bReading.load())
continue;
将永远不会被调用,因此在主线程循环中,您将始终通过is的此分支
main
意味着std::join
也将永远执行。
thread1.join()
用于从一个线程等待另一个线程完成其工作。当您从main
线程执行main
时,会发生thread1
将等待,直到@Path("/api")
public class Service1 {
final Logger logger = Logger.getLogger(Service1.class);
@POST
@Path("/testtransfer")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public String testtransfer(String name) throws SQLException {
logger.info("Service is:" + "InternalAccountTransfer");
PreparedStatement pstmt = null;
Connection conn = null;
FDIdGenerator f = new FDIdGenerator();
String Id = f.generate();
try
{
conn = DBUtil.getDataSource().getConnection();
}
catch(Exception e)
{
e.printStackTrace();
}
try{
pstmt = conn.prepareStatement(
"insert into EXTB_XML_REQ_RES(ID,SERVICE,OBX_REQ)values(?,?,?)");
pstmt.setString(1,Id);
pstmt.setString(2,"InternalAccountTransfer");
pstmt.setString(3,name);
System.out.println(pstmt + "......pstmt.....");
pstmt.executeUpdate();
conn.commit();
logger.info("REQ is:" + "Inserted");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{if(conn != null)
{
conn.close();
}
}
String START = "";
String END = "";
String Content = "";
String xml = "";
String response = "";
/* HashMap<String, String> response = new HashMap<String, String>(); */
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("config.properties");
Properties prop = null;
prop = new Properties();
try {
prop.load(in);
} catch (IOException e1) {
e1.printStackTrace();
}
String SOAPAction = prop.getProperty("SOAPACTION");
START = "<CREATETRANSACTION_FSFS_REQ xmlns=\"http://fcubs.ofss.com/service/FCUBSRTService\">\r\n";
BufferedReader br = null;
String sCurrentLine = "";
Content = name.substring(name.indexOf("<FCUBS_HEADER>"),
name.indexOf("</FCUBS_BODY>") + 13);
END = "</CREATETRANSACTION_FSFS_REQ>\r\n";
/* xml = XML.toString(json); */
xml = START + Content + END;
System.out.println(xml + "............xml...................");
xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:fcub=\""
+ SOAPAction
+ "FCUBSRTService\">\r\n"
+ " <soapenv:Header/>\r\n"
+ "<soapenv:Body>"
+ xml
+ " </soapenv:Body>\r\n" + "</soapenv:Envelope>";
System.out.println(xml + "...........xml........");
WebServiceCall wsc = new WebServiceCall();
logger.info("Before Calling The Webservice XML is :" + xml);
response = wsc.WebserviceInternalAccountTransfer(xml,Id);
return response.toString();
}
完成执行之前再执行任何其他指令。