c++ - 为什么程序在仅加入 1 个线程但有 5 个线程时可以正常工作

标签 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();
}

最佳答案

当您的 main 函数退出时, vector 中的所有线程都将被销毁。

如果他们当时没有加入 std::terminate 应该被 std::thread destructor 调用.


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

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


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

关于c++ - 为什么程序在仅加入 1 个线程但有 5 个线程时可以正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53194638/

相关文章:

c++ - 专门的哈希表c++

c++ - boost::condition 不存在 - condition 不是 boost 的成员

multithreading - `foreach` 过度并行收集永远不会开始

c - 使用编译器内部函数实现自旋锁以同步 OpenMP 线程

c++ - c++11 中 3 个线程和 2 个共享资源的同步问题

无符号整数中的 C++ 按位补码返回负值

c++ - 连接到 MySql 时 Qt Creator _IMP 错误

c# - 如何在循环中使用多个后台 worker ,在循环中为 C# 中的每个后台 worker 的每次迭代开始新工作

java - 如何优雅地停止在Eclipse中运行的Java主程序

c++ - 3.4.1 非限定名称查找