Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Stroustrup指的是std::async的哪些限制? 在他的《C++编程语言(第四版)》的“教程”第5.3.5.3章中,Bjarne Stroustrup写了 STD::AycY函数。_Multithreading_C++11_Asynchronous_Concurrency_Language Lawyer - Fatal编程技术网

Multithreading Stroustrup指的是std::async的哪些限制? 在他的《C++编程语言(第四版)》的“教程”第5.3.5.3章中,Bjarne Stroustrup写了 STD::AycY函数。

Multithreading Stroustrup指的是std::async的哪些限制? 在他的《C++编程语言(第四版)》的“教程”第5.3.5.3章中,Bjarne Stroustrup写了 STD::AycY函数。,multithreading,c++11,asynchronous,concurrency,language-lawyer,Multithreading,C++11,Asynchronous,Concurrency,Language Lawyer,这里有一个明显的限制:对于共享需要锁定的资源的任务,甚至不要考虑使用async(),使用async()您甚至不知道将使用多少线程,因为这取决于async()根据呼叫时对可用系统资源的了解来决定 类似的劝诫也可以在书中找到 “简单”是async();futures通常也可以用于线程,但不要考虑使用async()来启动执行I/O、操纵互斥体或以其他方式与其他任务交互的任务 有趣的是,当他在书的§42.4.6中更详细地回到C++11的并发特性时,他并没有详细阐述这个限制。更有趣的是,在本章中,他实际上

这里有一个明显的限制:对于共享需要锁定的资源的任务,甚至不要考虑使用
async()
,使用
async()
您甚至不知道将使用多少
线程,因为这取决于
async()
根据呼叫时对可用系统资源的了解来决定

类似的劝诫也可以在书中找到

“简单”是
async();futures通常也可以用于线程,但不要考虑使用
async()
来启动执行I/O、操纵互斥体或以其他方式与其他任务交互的任务

有趣的是,当他在书的§42.4.6中更详细地回到C++11的并发特性时,他并没有详细阐述这个限制。更有趣的是,在本章中,他实际上继续(与他网站上的声明相比):

async()
的一个简单而现实的用法是生成一个任务来收集用户的输入

根本没有提到任何此类限制

在阅读了一些最终形式的C++11标准的建议和讨论(很遗憾,我没有访问该标准的权限)之后,我了解到
async
很晚才被纳入C++11标准,并且有很多关于该功能应该有多强大的讨论。特别是,我发现这篇文章很好地总结了在实现
async
时必须考虑的问题

然而,所有讨论的问题都与
thread\u local
变量有关,这些变量在线程被回收时不会被破坏;如果线程在操作中切换其任务,并且两个任务分别持有
互斥体或
递归互斥体,则会出现虚假死锁或数据访问冲突,等等。这些对于功能的实现者来说是严重的问题,但是如果我理解正确的话,
async
的当前规范要求通过在调用者的线程上执行任务或者好像为任务创建了一个新线程一样,向用户隐藏所有这些细节

所以我的问题是:我不允许用
async
手动使用
thread
s做什么?这个限制的原因是什么?

例如,下面的程序有什么问题吗

#包括
#包括
#包括
#包括
静态整数计数{};
静态std::mutex tally_mutex{};
静态空隙
干活儿(施工总金额)
{
对于(int i=0;istd::cout你指出了问题所在。
线程可以循环使用。。。
因此,使用本地存储是危险的

您的循环是公正的,但是,正如您所提到的,可能是低效的

您可以要求该语言使用std::launch::async生成另一个线程。 但是线程仍然可以循环使用。

std::async的“问题”是默认情况下,您不知道它是否启动线程。如果您的函数需要在单独的线程上运行,那么这就是一个问题,因为在调用get()或wait()之前,您的函数可能不会运行。
您可以传递std::launch::async以确保函数在其自己的线程上启动,这就像无法分离BG e的std::线程一样。

如Stroustrup的示例所示-不要执行锁定,您很容易出现死锁,因为不能保证异步将在另一个线程中执行。在您的示例中,只需在ca之前锁定主函数中的互斥锁即可lling ASSYNC.@DmitriSosnik您能解释一下这到底是如何死锁的吗?在启动任务之前在主线程中获取一次互斥锁肯定不会死锁,但也会减少互斥锁的使用,并给
tally
一个垃圾值。无论如何,我的问题是
std::async
,而不是w这是将变量设置为1000000的最佳方法。谢谢。我想知道的是,如果我正确理解了标准,那么实现必须像创建了一个新线程(或直接在调用方的线程上执行任务)一样运行,即使它实际上回收了一个线程。那么,“危险”点在哪里呢使用
std::async
,但使用
std::thread
是安全的?但是,如果你能支持你的说法,即我的示例中的构造符合标准,我将接受你的答案。是的,这是有意义的。我将把这个答案视为“基本上没有约束”,因为对我来说,这个“问题”实际上只是
std::async
的语义,因此将其称为限制就好像说“不要使用
fread
写入文件”。当然,在实现生产者-消费者对时,将
std::async
与默认启动策略一起使用是一个非常糟糕的主意。