不调用Thread.join()时的C ++多线程异常

时间:2016-06-24 02:01:47

标签: c++ multithreading exception join

我有一个非常简单的程序,它给了我一个我不明白的例外。我有一个用Visual Studio Express 2012 for Desktop编写的C ++应用程序。

我创建了一个多线程应用程序,其中我有2个线程,一个调用一个人类,另一个调用另一个汽车类。

当我使用thread.join()时,我没有得到异常,但我没有得到所需的输出。当我注释掉thread.join()时,我得到了异常,但我也得到了所需的输出。

例外是: enter image description here

我只是想让两个线程同时执行和处理。 person和car类都有一个调用的方法,它使用线程休眠重复10次,它所做的就是打印一个字符串"开始行走"对于班级和"开始驾驶"对于汽车类而言,主线程只有等待......"

所以程序的输出是:

started walking
started driving
started walking
started driving
main waiting...
started walking
started driving
started walking
started driving
main waiting...

等。这就是我想要的。

如果我取消注释join方法,我会得到这个输出:

started walking
started walking
(repeat 8 more times)
started driving 
started driving
(repeat 8 more times)
Main waiting..
Main waiting..
(repeat 8 more times)

这不是我想要的。

如果不使用join()方法,如何在没有异常的情况下执行此应用程序?

作为一个FYI,这是我在下面创建的示例代码:

这是启动程序的主要方法。

include <iostream>
#include <thread>
#include <chrono>
#include "person.h"
#include "car.h"

int count1 = 0;
int count2 = 0;

int main()
{
    person p1;
    thread t1(&person::startWalking, p1);
    if(t1.joinable())
    {
        //t1.join();
    }

    car c1;
    thread t2(&car::startDriving, c1);
    if(t2.joinable())
    {
        //t2.join();
    }

    for(int x = 0; x < 10; x++)
    {
        std::cout<<"Main waiting...\n";//<<std::endl;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    return 0;
}

这是person.cpp文件:

#include "person.h"
person::person(void)
{
}
person::~person(void)
{
}
void person::startWalking()
{
    for(int x = 0; x < 10; x++)
    {
        cout<<"Started Walking.\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

void person::stopWalking()
{
    cout<<"Stopped Walking.\n";
}

这是car.cpp文件:

#include "car.h"

using namespace std;

car::car(void)
{
}
car::~car(void)
{
}
void car::startDriving()
{
    for(int x = 0; x< 10; x++)
    {
        std::cout<<"started driving\n.";
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

1 个答案:

答案 0 :(得分:0)

首先,document读取If the thread is joinable when destroyed, terminate() is called.,所以如果你对thread.join()和main函数的注释结束,那么线程必须调用析构函数并调用它terminate,此处terminateabort,因此您有例外!

如果您取消注释thread.join(),join方法returns when the thread execution has completed.,那么您将无法获得例外答案。

建议:

移动

if(t1.joinable())
{
    t1.join();
}

if(t2.joinable())
{
    t2.join();
}
std::this_thread::sleep_for(std::chrono::milliseconds(5000));之前

。你可以看到这三个线程同时执行,但你也无法得到你想要的结果,因为t1t2睡1秒,所以主线程将打印Main waiting...很快。因此,您应该对sleept1中的t2发表评论,或者为主要for中的每个循环添加相同的休眠时间。

提示:这三个线程将竞争并且输出缓冲区将被随机填充,因此输出将是不可预测的,您可以添加互斥锁以确保输出可读。

以下是我的代码:

#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>

std::mutex mMutex;

class person {
public:
    void startWalking()
    {
        for(int x = 0; x < 10; x++)
        {
            mMutex.lock();
            std::cout<< "Started Walking.\n";
            mMutex.unlock();
            //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
    }
};

class car {
public:
    void startDriving()
    {
        for(int x = 0; x< 10; x++)
        {
            mMutex.lock();
            std::cout <<"Started driving.\n";
            mMutex.unlock();
            //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
    }
};

int main()
{
    person p1;
    std::thread t1(&person::startWalking, p1);

    car c1;
    std::thread t2(&car::startDriving, c1);

    for(int x = 0; x < 10; x++)
    {
        mMutex.lock();
        std::cout <<"Main waiting...\n";
        mMutex.unlock();
        //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    t1.join();
    t2.join();
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    return 0;
}