我正在使用以下代码创建线程并将它们添加到线程池中。线程加载正常,每个执行一个简单的循环例程,直到主线程第二次调用ResetWorkerThreads并终止子线程。子线程被中断,但主线程也退出。没有错误写入控制台。我无法绕过它,因为它似乎没有任何异常,并且主线程尚未添加到vecThreads线程池中。此功能第二次全部“全部线程被杀”也不会输出,就好像它永远不会到达那一点。
std::string strPreviousSettings = "0";
std::string strPreviousAgentSettings = "0";
bool boolResetWorkers;
std::string strIP;
std::string strMACAddress;
boost::thread_group vecThreads;
std::string GetIP()
{
std::string strIP;
try
{
using namespace boost::network;
std::string strRequest;
http::client client;
http::client::request request("http://test.com/ip.php");
http::client::response response = client.get(request);
strIP = body(response);
}
catch(...)
{
cout << "GetLocalIP - Error: " << endl;
}
return strIP;
}
std::string getMacAddress()
{
std::string strMACAddress = GetFileContents("/sys/class/net/eth0/address");
boost::replace_all(strMACAddress, ":", "");
boost::replace_all(strMACAddress, "\n", "");
return strMACAddress;
}
void ThreadSettingsWorker()
{
int x = 1;
strIP = GetIP();
strMACAddress = getMacAddress();
do {
CheckEventSettings();
CheckAgentSettings();
if(boolResetWorkers==true)
{
ResetWorkerThreads();
} else {
boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
}
} while ( x != 0 );
}
void ResetWorkerThreads()
{
cout << "Resetting Workers Threads\n";
boolResetWorkers = false;
int intWorkerCount = 10; //Spawn 10 workers
int X = 0;
int intI = 1;
cout << "Kill All Threads\n";
try
{
vecThreads.interrupt_all();
}
catch(...)
{
//std::cerr << "Kill All Threads: " << std::endl;
}
cout << "All Threads Killed\n";
for (int i = 0; i < intWorkerCount; ++i)
{
cout << "Starting Worker: " << (i + 1) << "\n";
boost::thread tWorker(&ThreadWorker, (i + 1));
vecThreads.add_thread(&tWorker);
}
}
void TestRequest()
{
try
{
using namespace boost::network;
std::stringstream ss;
http::client client;
ss << "http://test.com/sadasdasd.html";
http::client::request request(ss.str());
http::client::response response = client.get(request);
std::string strOutput = body(response);
cout << "Test Request Out: " << strOutput << "\n";
}
catch(...)
{
cout << "TestRequest - Error: " << endl;
return;
}
}
void ThreadWorker(int intThread)
{
try
{
int X = 0;
do {
cout << "Thread " << intThread << "\n";
TestRequest();
} while ( X != 55 );
}
catch(...)
{
}
}
void CheckEventSettings()
{
try
{
using namespace boost::network;
std::string strRequest;
http::client client;
http::client::request request("http://test.com/events.php");
http::client::response response = client.get(request);
std::string strOutput = body(response);
if(strPreviousSettings==strOutput)
{
cout << "No Event Settings Changes\n";
} else {
cout << "Applying New Event Settings\n";
strPreviousSettings = strOutput;
std::string strDividerLine = "<br>";
std::string strDividerField = "<field>";
std::vector<std::string> vEvents;
vEvents = EasySplit(strOutput, strDividerLine);
for(std::vector<std::string>::const_iterator iEvent = vEvents.begin(); iEvent != vEvents.end() - 1; ++iEvent) {
}
}
}
catch(...)
{
cout << "CheckEventSettings - Error: " << endl;
return;
}
}
void CheckAgentSettings()
{
try
{
using namespace boost::network;
std::stringstream ss;
http::client client;
ss << "http://test.com/checksettings.php";
http::client::request request(ss.str());
http::client::response response = client.get(request);
std::string strOutput = body(response);
if(strPreviousAgentSettings==strOutput)
{
cout << "No Agent Settings Changes\n";
} else {
cout << "Applying New Agent Settings\n";
strPreviousAgentSettings = strOutput;
boolResetWorkers = true;
}
}
catch(...)
{
cout << "CheckAgentSettings - Error: " << endl;
return;
}
}
int main()
{
// Start thread
boost::thread tCheckSettings(&ThreadSettingsWorker);
// Ask thread to stop
//tCheckSettings.interrupt();
// Join - wait when thread actually exits
tCheckSettings.join();
return 0;
}
答案 0 :(得分:0)
您在此处有错误:
boost::thread tWorker(&ThreadWorker, (i + 1));
vecThreads.add_thread(&tWorker);
您创建一个本地对象tWorker
,在调用add_thread()
后删除该对象。所以vecThreads包含了thread
s的悬空指针。当您调用vecThreads.interrupt_all()
时,您会收到未定义的行为,因为vecThreads
尝试访问已删除的thread
对象,并且我认为您的程序因访问冲突或其他原因而终止。
您必须将代码更改为以下内容:
boost::thread* ptWorker = new boost::thread(&ThreadWorker, (i + 1));
vecThreads.add_thread(ptWorker);
请注意,您自己不需要delete
这些thread
个对象。 thread_group
delete
他们自己。
<强>此外:强>
terminate()
的问题可能是http::client
抛出异常的析构函数引起的。请尝试这样做,以便在TestRequest()
:
try{
http::client client;
try{
// other code
}
catch (){}
}
catch(){}
我还建议在vecThreads
之后重置interrupt_all()
。例如,您可以将其定义为boost::scoped_ptr
,然后在调用pvecThreads.reset(new boost::thread_group())
后执行interrupt_all()
。
目前,中断的线程在中断后仍然保留在thread_group
中,然后您再次尝试interrupt
它们以及稍后thread_group
中添加到ResetWorkerThreads()
的新线程。
答案 1 :(得分:0)
ResetWorkerThreads内部你有:
for (int i = 0; i < intWorkerCount; ++i)
{
cout << "Starting Worker: " << (i + 1) << "\n";
// One issue is here, don't create a thread on the stack
// and pass it to the thread group use new instead!
boost::thread tWorker(&ThreadWorker, (i + 1));
vecThreads.add_thread(&tWorker);
}
您正在将在堆栈上创建的线程添加到线程组。一旦遍历循环,线程内存就会失效。您将需要new
线程并将该指针传递给add_thread。