为什么仅加入1个线程却有5个线程

时间:2018-11-07 17:22:31

标签: c++ multithreading

这是我的代码,我无意中犯了一个错误,即没有使for循环更长,但是代码按预期工作。

程序完成后会发生什么?它是否有任何失败情况或计算机是否自动杀死了所有线程,并且如果有任何其他代码,它将再次出现线程问题(例如,如果我将启动2个线程,那么将有6个线程在工作,并且新的线程ID会是5和7?)

#include <iomanip>
#include <thread>
#include <iostream>
#include <mutex>
#include <sstream>
#include <vector>
#include <conio.h>

using namespace std;

bool endProgram = false;

struct Monitorius {
public:
    int IOCounter = 0;
    int readCounterC = 0;
    int readCounterD = 0;
    condition_variable cv;
    mutex mtx;
    int c = 10;
    int d = 100;

    Monitorius() {
        c = 10;
        d = 100;
        IOCounter = 0;
        readCounterC = 0;
        readCounterD = 0;
    }

    void changeC(int i) {
        while (!endProgram) {
            unique_lock<mutex> lck(mtx);
            cv.wait(lck, [&] {return readCounterC > 1; });
            if (!endProgram) {
                c += i;
                readCounterC = 0;
                cv.notify_all();
            }

        }
    }
    void changeD(int i) {
        while (!endProgram) {
            unique_lock<mutex> lck(mtx);
            cv.wait(lck, [&] {return readCounterD > 1; });
            if (!endProgram) {
                d -= i;
                readCounterD = 0;
                cv.notify_all();
            }
        }
    }
    void readCD(int i) {
        int oldC = -1;
        int oldD = -1;
        while (!endProgram) {
            unique_lock<mutex> lck(mtx);
            cv.wait(lck, [&] {return oldC != c && oldD != d; });
            if (!endProgram) {
                stringstream str;
                str << i << ": c:" << c << " d: " << d << endl;
                cout << str.str();
                readCounterC++;
                readCounterD++;
                IOCounter++;
                if (IOCounter >= 15)
                    endProgram = true;
                cv.notify_all();
                oldC = c;
                oldD = d;
            }
        }
    }
};

int main()
{
    Monitorius M;
    vector<thread> myThreads;

    myThreads.reserve(5);

    myThreads.emplace_back([&] { M.changeC(1); });
    myThreads.emplace_back([&] { M.changeD(2); });
    myThreads.emplace_back([&] { M.readCD(3); });
    myThreads.emplace_back([&] { M.readCD(4); });
    myThreads.emplace_back([&] { M.readCD(5); });

    for (size_t i = 0; i < 1; i++)
        myThreads[i].join();

    _getch();
}

1 个答案:

答案 0 :(得分:4)

退出main函数时,向量中的所有线程都会被破坏。

如果那时他们还没有加入,std::thread destructor应该调用std::terminate


通过分离线程,可以破坏线程对象,并且线程仍继续运行。但是,在普通的现代操作系统上,当进程结束时(发生在main返回或调用exit之后),无论如何线程将被杀死。为了让线程即使在“主”线程结束之后仍继续运行,您必须调用一个依赖于系统的函数以退出“主”线程。

我不知道是否可以在Windows上执行此操作,因为C ++代码不应该使用the ExitThread function,因为它会在不破坏对象的情况下退出线程。


解决这两个问题的方法当然是正确地加入所有线程。