使用MSVC编译的多线程应用程序在运行时失败

撕裂

我实现了一个周期性运行提供的函数的类。

//Timer.h
#include <chrono>
#include <mutex>
#include <thread>

class Timer {
public:
    Timer(const std::chrono::milliseconds period, const std::function<void()>& handler);
    ~Timer();
    void Start();
    void Stop();
    bool IsRunning() const;

private:
    const std::function<void()>& handler;
    const std::chrono::milliseconds period;
    bool isRunning = false;
    mutable std::recursive_mutex lock;
    int counter = 0;

    void DoLoop(int id);
};

//Timer.cpp
#include "Timer.h"

Timer::Timer(const std::chrono::milliseconds period, const std::function<void()>& handler) :handler(handler), period(period), lock(){}

Timer::~Timer() {
    Stop();
}

void Timer::Stop() {
    lock.lock();
    isRunning = false;  
    lock.unlock();
}

void Timer::Start() {
    lock.lock();
    if (!isRunning) {
        isRunning = true;
        counter++;
        std::thread(&Timer::DoLoop, this, counter).detach();
    }
    lock.unlock();
}

void Timer::DoLoop(int id) {
    while (true){
        std::this_thread::sleep_for(period);
        lock.lock();
        bool goOn = isRunning && counter==id;
        if (goOn) std::thread(handler).detach();
        lock.unlock();

        if (!goOn)
            break;
    }
}

bool Timer::IsRunning() const {
    lock.lock();
    bool isRunning = this->isRunning;
    lock.unlock();
    return isRunning;
}

这是一个简单的程序,看它是否有效:

void Tick(){ cout << "TICK" << endl; }

int main() {
    Timer timer(milliseconds(1000), Tick);
    timer.Start();
    cin.get();
}

当我使用g ++构建应用程序时,该程序可以构建并运行,没有任何问题。但是,当我使用Microsoft的编译器(v18)时,程序也会进行编译,但是在运行时会失败。

当我使用发布配置时,从其中一个线程得到以下异常:

Program.exe中0x000007F8D8E14A30(msvcr120.dll)的未处理异常:请求致命程序退出。

当我使用调试配置时,每秒都会弹出一个Microsoft Visual C ++运行时库错误:

调试错误!

程式:... \ path \ Program.exe

R6010-已调用abort()

在两种配置中:

  • 引发异常/错误开始在计时器循环的第二次迭代中弹出。

  • Tick即使thread(handler)被调用该程序也不会进入函数

  • 尽管错误跟踪时的堆栈跟踪在这两种配置中有所不同,但是它们都不包含我的代码中的任何内容。都以ntdll.dll!UserThreadStart(); 调试结束msvcr123d.dll!_NMSG_WRITE()于发行版本结束msvcr120.dll!abort()

为什么会出现问题,为什么只有在使用MSVC编译应用程序后才出现问题?这是某种MSVC的错误吗?还是应该更改编译器配置中的某些内容?

保罗

您的线程正在抛出std::bad_function_call,未处理异常,因此正在调用运行时abort()

变更:

const std::function<void()>& handler;

const std::function<void()> handler;

解决问题。我猜这是因为您在线程之间共享它?

如果创建本地并传递对该本地的引用,则也可以使用:

  const std::function<void()> f = Tick;
  Timer timer(std::chrono::milliseconds(1000), f);

因此,它一定超出了范围。

编辑:实际上,函数对象在ctor调用后被销毁了。不知道为什么会这样。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在运行时检测 MSIX 打包的应用程序

在运行时更改Polymer应用程序的主题

在运行时更改应用程序主题

在运行时更改应用程序MainForm

在运行时更改应用程序语言

在运行时设计 Angular 应用程序的样式

Web应用程序:在运行时删除文件

使用应用程序部署JSON文件并在运行时访问它

如何在运行时使用应用程序主机和端口

在运行时使用控制台输入调试打字稿应用程序

如何在运行时中检测到应用程序使用了Swift

如何使用 ContextCompat.checkSelfPermission() 在运行时检查 android 应用程序权限?

使用sbt构建的应用程序在运行时发生NoClassDefFoundError

如何在运行时使用Visual Studio调试Pygame应用程序

何时编译使用已更改的运行时程序包的应用程序

如何计算多线程程序的运行时间?

在基于Spring Boot的应用程序中使用REST API输入在运行时设置架构名称

如何使用Swift在运行时使我的应用程序表现得就像我在更改Application is agent(UIElement)?

如何在运行时应用程序中使用OpenCV Python在图像上写文本

是否可以在运行时使用angularAMD延迟加载角度模块并将其插入到应用程序中?

blazor wasm应用程序在运行时的程序集构建版本

在运行时替换MVC应用程序部分和Razor文件提供程序

运行时应用程序

Xamarin.Forms UWP应用程序在运行时因.net本机工具链失败,但可以正常运行

如何使用 wpf 创建一个应用程序,在运行时创建一个新应用程序?

更新到Android 3.6工作室后,在运行时应用程序崩溃

如何编写可以在运行时进行自我更新的Java应用程序?

更改compileSdkVersion是否会影响应用程序在运行时的行为?

如何在应用程序仍在运行时刷新它(活动)?