这是我的代码,我无意中犯了一个错误,即没有使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();
}
答案 0 :(得分:4)
退出main
函数时,向量中的所有线程都会被破坏。
如果那时他们还没有加入,std::thread
destructor应该调用std::terminate
。
通过分离线程,可以破坏线程对象,并且线程仍继续运行。但是,在普通的现代操作系统上,当进程结束时(发生在main
返回或调用exit
之后),无论如何线程将被杀死。为了让线程即使在“主”线程结束之后仍继续运行,您必须调用一个依赖于系统的函数以退出“主”线程。
我不知道是否可以在Windows上执行此操作,因为C ++代码不应该使用the ExitThread
function,因为它会在不破坏对象的情况下退出线程。
解决这两个问题的方法当然是正确地加入所有线程。