gpt4 book ai didi

c++ - 使用 std::async 引用对象

转载 作者:行者123 更新时间:2023-11-30 03:27:42 25 4
gpt4 key购买 nike

我在 visual studio 2012 中有一个小的解决方案。该解决方案由两个项目(Scanner 和 TestApp)组成,Scanner 是一个 dll,TestApp 是一个使用 dll 的小应用程序。我希望 dll 中的函数在线程中运行并通过队列将其结果报告回 TestApp。为了对此进行测试,我编写了一个最小的应用程序,但根据我启动线程的方式,我得到了不同的结果,我想了解其中的原因。

Scanner.h 文件如下所示:

#pragma once

#include <iostream>
#include <string>
#include <stdint.h>
#include <atomic>
#include <future>
#include <thread>

#include "version.h"
#include "threadsafe_queue.h"
#include "capture_data.h"
#include "process_data.h"


#ifdef SCANNER_EXPORTS
#define SCANNER_API __declspec(dllexport)
#else
#define SCANNER_API __declspec(dllimport)
#endif

class Scanner
{
public:
static SCANNER_API void run();
static SCANNER_API void stop();
};

扫描仪.cpp:

#include "stdafx.h"
#include "Scanner.h"

std::vector<std::future<int>> my_futures;

void Scanner::run()
{
CaptureData capture_data(1234);
auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);
my_futures.push_back(std::move(t));
}

void Scanner::stop()
{
for(int n=0; n<my_futures.size(); n++) {
auto e = std::move(my_futures.back());
e.get();
my_futures.pop_back();
}
}

CaptureData 类在 capture_data.h 和 capture_data.cpp 中定义。

capture_data.h:

#pragma once

#include <atomic>
#include <thread>
#include "iq_data.h"
#include "threadsafe_queue.h"

class CaptureData
{
public:
CaptureData(double freq_start);
void configure();
void get_data();
private:
double m_test;
};

capture_data.cpp

#include "stdafx.h"
#include "capture_data.h"
#include "Scanner.h"

ThreadsafeQueue<int> g_queue_1;
SCANNER_API ThreadsafeQueue<int> g_queue_2;


CaptureData::CaptureData(double test)
: m_test(test) {}

void CaptureData::get_data()
{
cout << "1: " << m_test << std::endl;
Sleep(5000);
cout << "2: " << m_test << std::endl;
g_queue_2.push(3);
cout << "Capture has now pushed data" << std::endl;
}

最后是 TestApp.cpp:

#include "stdafx.h"
#include "tchar.h"
#include <stdint.h>
#include <string>
#include "Scanner.h"


SCANNER_API extern ThreadsafeQueue<int> g_queue_2;

int _tmain(int argc, _TCHAR* argv[])
{
Scanner scanner;
scanner.run();
cout << "TestApp waiting for data..." << std::endl;
int data;
g_queue_2.wait_and_pop(data);
cout << "TestApp got data: " << data << std::endl;
scanner.stop();

return 0;
}

在 Scanner.cpp 中,我尝试以两种不同的方式启动线程,第一种方式:

auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);

第二种方式是引用对象“capture_data”:

auto t = std::async(std::launch::async, &CaptureData::get_data, &capture_data);

第一种方法似乎可以正常工作,因为我希望应用程序正常工作,并且我在终端中得到以下打印输出:

TestApp waiting for data... 
1: 1234
2: 1234
Capture has now pushed data
TestApp got data: 3
Press any key to continue...

如果我使用第二种方式,我会得到:

TestApp waiting for data... 
1: 6.95166e-310
2: 6.95166e-310
Capture has now pushed data
TestApp got data: 3
Press any key to continue...

所以,我不明白为什么变量“m_test”在第二种情况下会搞砸。如果有人能阐明这一点,我将不胜感激。

/M

最佳答案

在下面的代码中:

void Scanner::run()
{
CaptureData capture_data(1234);
auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);
my_futures.push_back(std::move(t));

capture_data 是一个超出范围并在函数返回时被销毁的局部变量。如果您将指向该变量的指针传递到 async 中,该指针将变成悬空指针,从而导致未定义的行为。如果您按值传递它,就不会发生这种情况,就像您在上面的代码片段中所做的那样。

关于c++ - 使用 std::async 引用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47155293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com