我有一个主线程,它初始化很少的数据结构并产生固定数量的线程。这些线程使用在主线程中创建的数据结构并与数据库交互。如果服务器返回任何错误,当与数据库服务器交互时,相应的线程将释放由主线程初始化的所有数据结构并调用exit()。 由于这些数据结构通常被所有线程使用,因此在释放数据结构后,当上下文切换到任何其他线程时,我会遇到崩溃问题。
我有一个解决这个问题的方法:释放并调用exit()作为1个单独的原子操作。这有用吗?
或者有任何方法在任何子导致错误时通知主线程,以便主线程可以相应地处理。我不能使用条件变量,因为它是一个阻塞操作。我希望我的主线程是非阻塞的。
以下是代码段:
#include <iostream>
#include <boost/thread.hpp>
Connection_Handler *conn;
boost::thread_group g;
void talk_to_server()
{
int result= 0;
// read query from a batch file //
result= conn->execute(query);
if (result)
{
// making below 2 statements as atomic solve my problem ?
delete conn;
exit();
}
}
int main(int argc, char* argv[])
{
conn = new Connection_Handler();
// launch three threads
boost::thread *t1 = new boost::thread(talk_to_server);
boost::thread *t2 = new boost::thread(talk_to_server);
boost::thread *t3 = new boost::thread(talk_to_server);
g.add_thread(&t1);
g.add_thread(&t2);
g.add_thread(&t3);
// wait for them
g.join_all();
return 0;
}
答案 0 :(得分:0)
简单的答案是Connection_Handler()对象的所有者是主线程,因此它应该是处置对象的主线程,而不是子线程。此外,子线程应该'return()'而不是'exit()',这样主线程就有机会处理它。
如果主线程需要非阻塞,则意味着它包含一些其他编程逻辑,这些逻辑与处理子线程的生命周期无关。因此[从软件工程的角度来看]我的建议是将这两个任务分开并将主线程拆分为两个更简单的线程:一个用于其他核心活动,另一个用于处理线程。通过这种方式,您可以使线程处理程序等待条件变量或子线程死亡,并在退出之前执行适当的资源清理。
有关如何使用Boost条件变量的信息,请参阅,例如How do I use a boost condition variable to wait for a thread to complete processing?或Have main thread wait for a boost thread complete a task (but not finish)。
只是我的两分钱。