【问题标题】:Running threads from within classes从类中运行线程
【发布时间】:2019-10-06 21:48:15
【问题描述】:

我正在尝试一次执行两个操作,一个循环在程序的 main 方法中打印出Tick from main,另一个循环在一个类中打印出Tick from ConnectionManager

我在此处运行的这段特定代码取自此处提出的问题之一。

main.cpp 文件:

#include <Windows.h> // printf, Sleep
#include <thread> // thread

// Include Connection Manager
#include "ConnectionManager.h"

int main() {
    ConnectionManager _CM;

    while (1) {
        printf("Tick from main");
        Sleep(1500);
    }
}

ConnectionManager.h

#pragma once
class ConnectionManager
{
private:
    void LoopForData();
public:
    ConnectionManager();
};

ConnectionManager.cpp

#include "ConnectionManager.h"

#pragma once
#include <Windows.h>
#include <thread>

void ConnectionManager::LoopForData() {
    while (1) {
        printf("Tick from connection manager\n");
        Sleep(1500);
    }
}

ConnectionManager::ConnectionManager()
{
    std::thread tobj(&ConnectionManager::LoopForData, this);
}

预期的行为是两个循环同时运行,但是我在控制台上得到的输出仅来自 LoopF​​orData 函数,并且我得到了这个错误屏幕:https://imgur.com/a/WO5AKE8

我可能会错过什么?

【问题讨论】:

  • 因为 printf 是不可重入的,你应该看看stackoverflow.com/q/3941271/2477299
  • ConnectionManager() 函数退出时会发生什么?
  • @vahancho 随着构造方法完成执行 LoopF​​orData() 每 1500 毫秒调用一次,错误就会出现,并且 main 函数中的 while 循环不会被执行。
  • 我相信 printf 有一个锁,可以防止跨多个线程同时访问。一次只有一个线程可以访问 printf。
  • 对于 C++,你应该更喜欢 cout。

标签: c++ multithreading class runtime-error


【解决方案1】:

这应该可以正常工作。

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

//ConnectionManager.h
class ConnectionManager
{
private:
    std::thread tobj;
public:

    ConnectionManager();
    ~ConnectionManager();
private:
    void LoopForData();
};
//ConnectionManager.cpp
#include "ConnectionManager.h"

void ConnectionManager::LoopForData(){
    while (1) {
        std::cout << "Tick from connection manager" << std::endl;
        std::this_thread::sleep_for (std::chrono::milliseconds(1500));
    }
}
ConnectionManager::~ConnectionManager(){
    if(tobj.joinable()){
        tobj.join();
    }
}
ConnectionManager::ConnectionManager() : tobj(&ConnectionManager::LoopForData, this){

}
//main.cpp

#include "ConnectionManager.h"
int main() {
    ConnectionManager _CM;

    while (1) {
        std::cout << "Tick from main" << std::endl;
        std::this_thread::sleep_for (std::chrono::seconds(1));
    }
}

我认为您的主要问题与构造函数退出时 tobj 超出范围有关。您也可以使用 c++ 标准睡眠代替 Windows 中的睡眠。

【讨论】:

  • 显示单独的文件以及 chrono::milliseconds 和 chrono::seconds
  • @TedLyngmo 是的,我的意思是输入原始代码。
  • @TedLyngmo 完成。
猜你喜欢
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多