C++ C++;boost threadgroup.interrupt_all()导致主线程也退出

C++ C++;boost threadgroup.interrupt_all()导致主线程也退出,c++,multithreading,boost,C++,Multithreading,Boost,我使用下面的代码创建线程并将它们添加到线程池中。线程加载良好,每个线程执行一个简单的循环例程,直到主线程第二次调用ResetWorkerThreads并杀死子线程。子线程被中断,但主线程也退出。没有写入控制台的错误。我不能把我的头绕到它身上,因为它似乎没有任何异常,并且主线程还没有添加到vecThreads线程池中。第二次执行此函数时,所有“已终止的所有线程”都不会输出,就好像它从未到达该点一样 std::string strPreviousSettings = "0"; std::string

我使用下面的代码创建线程并将它们添加到线程池中。线程加载良好,每个线程执行一个简单的循环例程,直到主线程第二次调用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;

}
std::string strPreviousSettings=“0”;
std::string strPreviousAgentSettings=“0”;
bool-boolResetWorkers;
std::字符串条;
std::字符串strmacadress;
boost::thread\u组vecThreads;
std::string GetIP()
{
std::字符串条;
尝试
{
使用名称空间boost::network;
std::字符串strequest;
http::客户端;
http::客户端::请求请求(“http://test.com/ip.php");
http::client::response=client.get(请求);
条=主体(响应);
}
捕获(…)
{

您在这里可能有一个错误:

boost::thread tWorker(&ThreadWorker, (i + 1));
vecThreads.add_thread(&tWorker);
您创建了一个本地对象
tWorker
,该对象在调用
add_thread()
后立即被删除。因此,vecThreads包含指向
thread
s的悬空指针。当您调用
vecThreads时。中断\u all()
由于
vecThreads
尝试访问已删除的
thread
对象,您会得到未定义的行为,我想您的程序只是因为访问冲突或其他原因而终止

您必须将代码更改为以下内容:

boost::thread* ptWorker = new boost::thread(&ThreadWorker, (i + 1));
vecThreads.add_thread(ptWorker);
请注意,您不需要自己
删除
那些
线程
对象。
线程组
自己删除它们

添加:
terminate()
的问题可能是由
http::client
的析构函数引发异常引起的。请尝试此操作,以可能在
TestRequest()中消除该问题。

此外,我还建议在
interrupt_all()
之后重置
vecThreads
。例如,您可以将其定义为
boost::scoped_ptr
,然后执行
pvecThreads.reset(新的boost::thread_group())
调用
interru all()


目前,中断后的线程仍保留在
thread\u组中
,然后您尝试
再次中断
这些线程,以及随后在
ResetWorkerThreads()
ResetWorkerThreads()中添加到
thread\u组中的新线程

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);
}
for(inti=0;i你能发布一个小版本的main和一个线程作业来演示这个行为吗?在你调用这个函数的站点上,或者在调用中断后的线程循环中,可能会发生一些事情,这可能会给你带来问题。已经发布了额外的代码,谢谢。仍然有一些问题这可能就是问题所在。我建议你从最简单的例子开始,在一个线程中使用一个池和中断。如果可行,开始放慢添加代码的速度,直到代码中断。这将缩小失败的范围,并导致你看到的行为。不过,我确实看到了一个问题,我会将其添加到答案部分。我有e对指针进行了调整,但现在我面临一个新错误,在抛出“boost::exception\u detail::clone\u impl”what()的实例后调用terminate:boost线程:尝试加入自身:资源死锁avoided@user246181请尝试从
try
块内部移动声明
http::client;
。因此代码应该是
http::client;try{…}
而不是
try{http::client;..}
@user246181您应该在所有函数中都这样做。我已经在TestRequest()中注释掉了HTTP请求代码函数,现在我得到了下面的消息,主线程仍然存在。boost::thread_interrupted'terminate调用递归终止调用递归终止调用递归终止调用递归终止调用递归终止我开始认为错误现在存在于以下代码中,在它作为cout c第二次执行之后执行此代码之前的所有操作,然后应用程序终止
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);
}