111*_*111 70 c++ multithreading deadlock c++11
我通过线程获得C++错误:
terminate called without an active exception
Aborted
Run Code Online (Sandbox Code Playgroud)
这是代码:
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template<typename TYPE>
class blocking_stream
{
public:
blocking_stream(size_t max_buffer_size_)
: max_buffer_size(max_buffer_size_)
{
}
//PUSH data into the buffer
blocking_stream &operator<<(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.size()>=max_buffer_size)
stop_if_full.wait(mtx_lock);
buffer.push(std::move(other));
mtx_lock.unlock();
stop_if_empty.notify_one();
return *this;
}
//POP data out of the buffer
blocking_stream &operator>>(TYPE &other)
{
std::unique_lock<std::mutex> mtx_lock(mtx);
while(buffer.empty())
stop_if_empty.wait(mtx_lock);
other.swap(buffer.front());
buffer.pop();
mtx_lock.unlock();
stop_if_full.notify_one();
return *this;
}
private:
size_t max_buffer_size;
std::queue<TYPE> buffer;
std::mutex mtx;
std::condition_variable stop_if_empty,
stop_if_full;
bool eof;
};
Run Code Online (Sandbox Code Playgroud)
我在这个例子中模拟了我的代码:http: //www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
我做错了什么,如何修复错误?
Bar*_*ski 98
当线程对象超出范围并且处于可连接状态时,程序将终止.标准委员会对可连接线程的析构函数有两个其他选项.它可以安静地加入 - 但是如果线程被卡住,加入可能永远不会返回.或者它可以分离线程(分离的线程不可连接).但是,分离的线程非常棘手,因为它们可能会持续到程序结束并且会释放资源.因此,如果您不想终止您的程序,请确保您加入(或分离)每个线程.
Eri*_*ski 40
如何重现该错误:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译并运行:
el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
terminate called without an active exception
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
您收到该错误是因为您没有加入或分离您的主题.
修复它的一种方法是,加入这样的线程:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main() {
std::thread t1(task1, "hello");
t1.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后编译并运行:
el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
task1 says: hello
Run Code Online (Sandbox Code Playgroud)
修复它的另一种方法是将它分开:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main()
{
{
std::thread t1(task1, "hello");
t1.detach();
} //thread handle is destroyed here, as goes out of scope!
usleep(1000000); //wait so that hello can be printed.
}
Run Code Online (Sandbox Code Playgroud)
编译并运行:
el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
task1 says: hello
Run Code Online (Sandbox Code Playgroud)
阅读有关分离C++线程和加入C++线程的信息.
har*_*nan 17
Eric Leschinski和Bartosz Milewski已经给出了答案.在这里,我将尝试以更加初学者友好的方式呈现它.
一旦在一个作用域(它本身在一个线程上运行)中启动了一个线程,就必须在线程超出作用域之前明确地确保发生以下一种情况:
注意,在线程连接或分离时,它可能已经完成执行.仍然必须明确地执行这两个操作中的任何一个.