我相当熟悉C++ 11的std::thread,std::async和std::future部件(例如见这个答案),这是直接的.
但是,我不能完全理解std::promise它是什么,它做什么以及在哪种情况下最好使用它.标准文档本身不包含其类概要之外的大量信息,也不仅仅是:: thread.
有人可以给出一个简短,简洁的例子,说明std::promise需要哪种情况以及最惯用的解决方案?
在使用C++ 11的线程模型时,我注意到了这一点
std::packaged_task<int(int,int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
task(2,3);
std::cout << f.get() << '\n';
Run Code Online (Sandbox Code Playgroud)
和
auto f = std::async(std::launch::async,
[](int a, int b) { return a + b; }, 2, 3);
std::cout << f.get() << '\n';
Run Code Online (Sandbox Code Playgroud)
似乎做了完全相同的事情.据我所知,有可能是一个重大的区别,如果我跑std::async带std::launch::deferred,但有一个在这种情况下?
这两种方法有什么区别,更重要的是,我应该使用哪种用例?
以前,我曾经使用MFC的集合类CArray和CMap.过了一会儿,我换了STL容器,并且已经使用了一段时间.虽然我发现STL要好得多,但我无法明确指出它的确切原因.一些推理如:
我可以提出的唯一原因是我可以在容器上使用算法.我在这里缺少任何其他原因 - 是什么让STL容器比MFC容器更好?
我有一个基于MFC的大型应用程序,它包含主线程中一些可能非常慢的任务.这可以给出应用程序在实际执行长任务时挂起的外观.从可用性的角度来看,我想向用户提供更多关于进度的反馈,并且可以选择以干净的方式中止任务.虽然将长任务分解为单独的线程将是一个更好的长期解决方案,但我认为一个实用的短期解决方案是创建一个新的GUI线程,封装在自己的对象中,包括进度条和取消按钮,用于与CWait对象类似的方式.主线程通过IsCancelled方法监视取消状态,并在需要时通过throw完成.
这是一种合理的方法吗?如果有的话,那里有一些我可以使用的MFC代码,或者我应该自己编写?第一幅草图看起来像这样
class CProgressThread : public CWinThread
{
public:
CProgressThread(int ProgressMax);
~CProgressThread()
void SetProgress(int Progress);
BOOL IsCancelled();
private:
CProgressDialog *theDialog;
}
void MySlowTask()
{
CProgressThread PT(MaxProgress);
try
{
{
{ // deep in the depths of my slow task
PT.SetProgress(Progress);
if (PT.IsCancelled())
throw new CUserHasHadEnough;
}
}
}
catch (CUserHasHadEnough *pUserHasHadEnough)
{
// Clean-up
}
}
Run Code Online (Sandbox Code Playgroud)
作为一项规则,我倾向于有一个GUI线程和许多工作线程,但这种方法可能会省去一堆重构和测试.任何严重的潜在陷阱?
我有一个 Win32 程序,我想在其中添加一些 winRT 调用。除其他外,我想打开一个没有 GUI 界面的文件。
我使用来自 StorageFile 类的异步文件打开调用,因为下一个调用需要一个 IStorageFile 接口。
#include <roapi.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.h>
void openFile()
{
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Storage;
HRESULT rtn = RoInitialize(RO_INIT_MULTITHREADED);
winrt::hstring path{ L"C:\\Users...\\mytextfile.txt"};
//wait for open the file
auto file = co_await StorageFile::GetFileFromPathAsync(path);
//IStorageFile interface needed
}
int main()
{
openFile();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
目前,编译器抱怨 co_await 表达式需要一个合适的“await_ready”函数,但没有找到。
我不确定是否是由于缺少标头包含或在 win32 应用程序中无法使用“co_await”而导致的这种情况。
编辑:我的 Visual Studio 项目设置是: - 使用 c++17,将 cppwinrt.exe 添加到我的包含目录,链接到 windowsapp.lib 并使用 windows sdk 版本 10.0.17134.0。
我有一个C++/MFC应用程序,我需要重组.该应用程序用于处理大部分在主线程中的数据,从而阻断输入,现在我想改变它的话,所有的GUI更新是通过PostMessage的完成.
不幸的是,我似乎找不到如何实现这一目标的良好来源.
现在我正在考虑创建一个优先级队列,使用临界区保护,一个处理此队列的工作线程(while(true)),以及将数据指针发送到主线程的PostMessage机制.
使用这种方法让我害怕的是PostMessage根本不能保证到达主线程,所以,如果我理解正确,就有可能发生内存泄漏.
第二个问题是另一个应用程序可以向我的应用程序发送自定义消息,我的应用程序可能会尝试取消引用WPARAM或LPARAM作为指针,从而导致AV.
有谁知道这些任务的最佳实践是什么?
数据可以是用于Web控件的HTML内容,也可以是列表框,下拉列表等的其他内容.
c++ ×6
mfc ×3
c++11 ×2
c++-winrt ×1
containers ×1
postmessage ×1
promise ×1
stdasync ×1
stl ×1
winapi ×1