实现多线程后"Project.exe has triggered a breakpoint"
"Project.exe has triggered a breakpoint" after implementing multithreading
我有一个Visual Studio项目,在我尝试实现multithreading
之前工作正常。该项目从GigE
相机获取图像,在获取10张图像后,从获取的图像制作视频。
程序流程使得程序在制作视频时不会获取图像。我想改变这一点,所以我创建了另一个线程来制作图像中的视频。我想要的是程序将连续获取图像,在获取 10 张图像后,另一个线程并行运行以制作视频。这将持续到我停止程序,获取 10 张图像,从这 10 张图像中并行制作视频,同时采集接下来的 10 张图像,依此类推。
我以前没有创建过threads
,所以我按照这个网站上的教程进行操作。与网站类似,我为保存视频的function
创建了一个thread
。创建视频的function
将 10 张图像作为vector
参数。我在这个线程上执行join
,就在main
函数终止的行之前。
为了清楚起见,以下是我实现的伪代码:
#include ...
#include <thread>
using namespace std;
thread threads[1];
vector<Image> images;
void thread_method(vector<Image> & images){
// Save vector of images to video
// Clear the vector of images
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
threads[0] = thread(thread_method, images)
}
// stuff
threads[0].join();
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return 0;
}
当我现在运行项目时,弹出一条消息,指出项目.exe触发了断点。该项目在static bool __cdecl issue_debug_notification(wchar_t const* const message) throw()
年中断report_runtime_error.cpp
。
我正在控制台上打印一些cout
消息,以帮助我了解正在发生的事情。发生的情况是程序获取10张图像,然后保存视频的thread
开始运行。由于有 10 张图像,因此必须将 10 张图像附加到视频中。第二次获取 10 张图像后,弹出 Project.exe 已触发断点的消息,此时并行线程仅将第一组采集的图像中的 6 张图像附加到视频中。
输出包含多行thread XXXX has exited with code 0
,之后输出显示
Debug Error!
Program: ...PathProgram.exe
abort() has been called
(Press Retry to debug the application)
Program.exe has triggered a breakpoint.
我无法在评论中解释所有这些。我把它放在这里,因为看起来 OP 正朝着一些糟糕的方向前进,我想在悬崖之前阻止他。Caleth抓住了大爆炸,并提供了避免它的解决方案,但爆炸只是OP的症状,detach
的解决方案有些值得怀疑。
using namespace std;
为什么"使用命名空间 std"被认为是不好的做法?
thread threads[1];
数组 1 几乎毫无意义。如果我们不知道会有多少线程,请使用vector
.另外,没有充分的理由将其作为全局变量。
vector<Image> images;
同样,没有充分的理由认为这是全球性的,还有很多理由不是全球性的。
void thread_method(vector<Image> & images){
按引用传递可以节省一些复制,但 A( 您无法复制引用,线程会复制参数。好的,所以使用指针或std::ref
。您可以复制这些内容。但你通常不想。问题 1:多个线程使用相同的数据?最好是只读的,或者防止并发修改。这包括生成vector
的线程。2. 参考资料是否仍然有效?
// Save vector of images to video
// Clear the vector of images
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
threads[0] = thread(thread_method, images)
由于卡莱斯涵盖的原因而变得糟糕。此外,images
还在不断增长。第一个线程,即使复制,也有十个元素。第二个有前十个加上另外十个。这很奇怪,可能不是OP想要的。对这种vector
的引用或指针是致命的。当其他线程正在使用vector
时,将被调整大小,从而使旧数据存储失效,并使其无法安全地迭代。
}
// stuff
threads[0].join();
由于卡莱斯所涵盖的原因而错误
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return 0;
}
在线程上加入的解决方案与几乎所有未解决为"使用std::string
"的堆栈溢出问题相同:使用std::vector
。
#include <iostream>
#include <vector>
#include <thread>
void thread_method(std::vector<int> images){
std::cout << images[0] << 'n'; // output something so we can see work being done.
// we may or may not see all of the numbers in order depending on how
// the threads are scheduled.
}
int main() // not using arguments, leave them out.
{
int count = 0; // just to have something to show
// no need for threads to be global.
std::vector<std::thread> threads; // using vector so we can store multiple threads
// Some stuff
while(count < 10) // better-defined terminating condition for testing purposes
{
// every thread gets its own vector. No chance of collisions or duplicated
// effort
std::vector<int> images; // don't have Image, so stubbing it out with int
for (int i = 0; i < 10; i++)
{
images.push_back(count);
}
// create and store thread.
threads.emplace_back(thread_method,std::move(images));
count ++;
}
// stuff
for (std::thread &temp: threads) // wait for all threads to exit
{
temp.join();
}
// std::endl is expensive. It's a linefeed and s stream flush, so save it for
// when you really need to get a message out immediately
std::cout << "nDone! Press Enter to exit..." << std::endl;
char temp;
std::cin >>temp; // sticking with standard librarly all the way through
return 0;
}
为了更好地解释
threads.emplace_back(thread_method,std::move(images));
这在threads
(emplace_back
(内部创建了一个thread
,它将用images
的副本调用thread_method
。编译器很有可能会认识到这是这个特定images
实例的终点并消除复制,但如果不是,std::move
应该给它提示。
你在 while 循环中覆盖了一个线程。如果它仍在运行,则程序将中止。您必须联接或分离每个线程值。
你可以改为做
#include // ...
#include <thread>
// pass by value, as it's potentially outliving the loop
void thread_method(std::vector<Image> images){
// Save vector of images to video
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
std::vector<Image> images; // new vector each time round
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
// std::thread::thread will forward this move
std::thread(thread_method, std::move(images)).detach(); // not join
}
// stuff
// this is somewhat of a lie now, we have to wait for the threads too
std::cout << std::endl << "Done! Press Enter to exit..." << std::endl;
std::getchar();
return 0;
}
- 'Project.exe has triggered a breakpoint.'
- "Build succeeded"但"The breakpoint will not currently be hit"
- 使用模板时获取"Trigger Breakpoint Error at delete"
- 实现多线程后"Project.exe has triggered a breakpoint"
- 为什么删除执行组件指针会导致"Program.exe has triggered a breakpoint"
- QComboBox not triggered
- 一个奇怪的"Project.exe has triggered a breakpoint."?
- 调试混合模式应用程序(C# 和非托管 C++)时"The breakpoint will not currently be hit"错误
- "The breakpoint will not currently be hit. No symbols have been loaded for this document." Visual S
- 对所有断点运行"breakpoint command list"/迭代断点 [GDB]
- "The breakpoint will not currently be hit" - 我无法添加.pdb文件
- Visual Studio 2015 Update 1 C++ "The breakpoint failed to bind"
- MSVC "the breakpoint will not currently be hit"
- QGraphicsItem setPos() not triggered
- Qt paintevent() not triggered
- "Project.exe has triggered a breakpoint" p_array++ 之后;在 Visual Studio 2015 中