首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

调用async生成新的线程,那么作为调用者的原线程,是否必须调用future.get()或者wait_for()函数来保证async生成线程的结束早于async返回future对象的析构?

作为一个专家,我认为这个问题是关于C++中的异步编程和线程管理的。在这个问题中,提到了使用async生成新的线程,并讨论了调用者线程是否需要调用future.get()wait_for()函数来保证新线程的结束时间早于async返回future对象的析构。

首先,async是C++11引入的一种异步编程机制,它可以帮助开发者更容易地编写并发代码。async接受一个可调用对象和一系列参数,并在后台线程中异步地执行该可调用对象。它返回一个std::future对象,该对象可用于查询任务的结果或等待任务完成。

在这个问题中,提到了async生成的新线程,这意味着一个独立于调用者线程的线程正在执行任务。如果调用者线程不等待新线程完成,那么新线程可能在调用者线程结束之前被异常终止。这可能导致未定义的行为或资源泄漏。

因此,为了确保新线程的正常结束,调用者线程应该使用future.get()wait_for()等待新线程完成。future.get()将阻塞调用者线程,直到新线程完成并返回结果。wait_for()允许调用者线程等待一定时间,然后继续执行。如果新线程在指定时间内完成,wait_for()将返回std::future_status::ready,否则将返回std::future_status::timeout

总之,为了确保async生成的新线程能够正常结束,调用者线程应该使用future.get()wait_for()等待新线程完成。这可以避免在调用者线程结束之前意外终止新线程,从而导致未定义的行为或资源泄漏。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Chapter 7: The Concurrency API

调用std::async并不保证会创建一个新的软件线程,而是它允许调度器把新线程要执行的函数放在当前线程上运行,当前线程是请求新线程并等待执行结果的线程,那么当系统过载或者线程资源不够时,合理的调度器会利用自由方式来解决这些问题...这种机制保证函数运行在一个不同的线程中 std::launch::deferred 启动机制,这种机制使得当std::async返回的future对象调用了get或者wait时,异步函数才会被执行。...的future会调用get或者wait函数,要么也能接受异步任务不会被执行的结果 用到wait_for或者wait_until的代码考虑到延迟任务类型的可能性 3....因为调用者的future和被调用者的promise在传递结果时,这个结果既没有存放在promise,也没有存放在future,而是存放在一个堆对象代表的shared state中,而标准没有指定个对象的行为...对象如果被最后一个future引用,那么这个future在析构时就会阻塞 触发条件: future引用一个由std::async产生的shared state对象 任务的启动策略是

91150

再也不用std::thread编写多线程了

如果申请的软件线程数量多于系统可以提供的,调用std::thread会抛出异常,然而调用std::async时 系统不保证会创建一个新的软件线程,相反,它允许调度器把指定函数(doAsyncWork...false或者抛出了异常,那么在doWork的末尾调用std::thread型别对象t的析构函数时 * 它会处于可联结合=状态,从而导致程序执行终止 * */ } void...,在被调方结束后会实施析构 * * 2,该结果也不能存储在调用方的期望值中,因为可能会从 std::future型别对象出发创建 std::shared_future型别对象, * 因此把被调方结果的所有权从...* 本质上,这样一个期望值的析构函数是对底层异步执行任务的线程实施了一次隐式 join * * 2,其他所有期望值对象的析构函数只仅仅将期望值对象析构就结束了。...没有提供任何办法判断其指涉的共享状态是否诞生于 std::async 的调用,所以给定任意期望对象的前提下,它不可能知道自己是否会在析构 //函数中阻塞到异步任务执行结束 //该容器的析构函数可能会在其析构函数中阻塞

2.4K40
  • C++11异步编程(std::async, std::future, std::packaged_task, std::promise)

    在之前我们都是通过thread去创建一个子线程,但是如果我们要得到这个子线程所返回的结果,那么可能就需要用全局变量或者引用的方法来得到结果,这样或多或少都会不太方便,那么async这个函数就可以将得到的结果保存在...future提供了一些函数比如get(),wait(),wait_for(),一般用get()来获取future所得到的结果,如果异步操作还没有结束,那么会在此等待异步操作的结束,并获取返回的结果。...std::async        其实这个函数是对上面的对象的一个整合,async先将可调用对象封装起来,然后将其运行结果返回到promise中,这个过程就是一个面向future的一个过程,最终通过future.get...它的实现方法有两种,一种是std::launch::async,这个是直接创建线程,另一种是std::launch::deferred,这个是延迟创建线程(当遇到future.get或者future.wait...那么std::async的第二个参数就是可调用对象的名称,第三个参数就是可调用对象的参数。

    16.1K30

    c++11 多线程入门教程(一)

    在lock_guard对象被析构时,它所管理的mutex对象会自动解锁,不需要程序员手动调用lock和unlock对mutex进行上锁和解锁操作。...假设线程1需要线程2的数据,那么组合使用方式如下:     线程1初始化一个promise对象和一个future对象,promise传递给线程2,相当于线程2对线程1的一个承诺;future相当于一个接受一个承诺...获取future的结果有三种方式上面是get()获取异步结果值返回,还有wait()等待异步操作完成,以及wait_for()超时等待返回结果。  ...5.future与package_task的使用   std::packaged_task包装一个可调用的对象,并且允许异步获取该可调用对象产生的结果。...std::launch::deferred:延迟加载方式创建线程。调用async时不创建线程,直到调用了future的get或者wait时才创建线程。

    94420

    std future get_waitkey(0)

    }; 1.2 wait_for(): 返回值类型为future_status,该函数将本线程阻塞在当前,并等待一段时间,后继续执行,若在等待时间内wait_for()绑定线程执行完毕,则返回ready...cout << "deferred act" << endl; cout << result.get(); } 注意:无论std::async()是否延迟执行,异步线程都将会指向完程序才能结束,三种结束方式...: 阻塞在wait_for()处等待异步线程结束 阻塞在get()处等待异步线程结束 阻塞在return 0;处等待异步线程结束 get()函数只能使用一次,因为get()函数的设计是一个移动语义,相当于将...future对象中的值转移到了get()调用者中,所以再次get()就报告了异常。...初始化std::shared_future对象,通过std::shared_future即可多次调用get()获取线程返回。

    39730

    UNIX(多线程):19---Future 类型详解

    对象调用 get(通常在另外一个线程中) 获取该值,如果共享状态的标志不为 ready,则调用 std::future::get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值(此时共享状态的标志变为...在一个有效的 future 对象上调用 get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值或异常(此时共享状态的标志变为 ready),std::future::get 将返回异步任务的值或异常...(); // when T is void 当与该 std::future 对象相关联的共享状态标志变为 ready 后,调用该函数将返回保存在共享状态中的值,如果共享状态的标志不为 ready,则调用该函数会阻塞当前的调用者...() 可以设置一个时间段 rel_time,如果共享状态的标志在该时间段结束之前没有被 Provider 设置为 ready,则调用 wait_for 的线程被阻塞,在等待了 rel_time 的时间长度后...wait_for() 返回,返回值如下: 返回值 描述 future_status::ready 共享状态的标志已经变为 ready,即 Provider 在共享状态上设置了值或者异常。

    60020

    CC++开发基础——std::future与async异步编程

    一,std::future与std::promise std::future是一个类模板,存放了线程入口函数的返回结果,调用std::future对象的get()函数可以拿到返回结果。...std::future可以先通过调用wait_for()方法,查询结果是否可用来避免阻塞。 std::future只能调用一次get()成员函数来获取结果,继续调用多次会引发异常。...三,std::async使用说明 std::async是一个函数模板,通常用来启动一个异步任务,std::async执行结束会返回一个std::future对象。...std::thread创建的线程不容易获取线程函数的返回值,std::async执行完返回一个std::future对象,可以很容易获取线程函数的返回值。...,方便作为线程的入口函数来调用。

    1.1K10

    【C++11】std::async函数介绍及问题梳理

    >::type>:这是 std::async 函数的返回类型。它是一个 std::future 对象,包装了函数 F 的返回类型。...如果任务在新线程中执行,并且在该新线程中发生了内存分配失败,那么系统会终止整个程序,而不是将异常传递回调用 std::async 的地方【这是因为线程的异常不能跨线程传递】 这是因为C++的异常处理机制不能跨线程传播...如果异常发生在 std::async 创建的新线程中,并且在那里没有被捕获,那么整个线程会终止,但异常不会被传递回调用 std::async 的线程。...所以,如果在 std::async内部发生了内存分配失败,程序通常会终止并可能会生成错误报告,而不是抛出异常到 std::async 的调用者。...然后调用 future.get() 等待异步任务完成,并获取其结果。如果异步任务中抛出了异常,future.get() 函数会在主线程中抛出相同的异常。

    61010

    Python asyncio之协程学习总结

    此函数总是会创建一个新的事件循环并在结束时关闭之。它应当被用作 asyncio 程序的主入口点,理想情况下应当只被调用一次。...add_done_callback(fn) 添加一个回调,以便在future完成时运行。 使用一个future对象作为参数调用回调。...所有future必须共享相同的事件循环。如果所有task都成功完成,那么返回的future结果就是结果列表(按照原始序列的顺序,不一定是结果到达的顺序)。...asyncio.iscoroutine(obj) 如果obj是一个协程对象,该对象可能基于生成器或async def协程,则返回True。...FIRST_EXCEPTION 当任何future因为引发异常而结束时,函数将返回。如果没有future引发异常,那么它相当于ALL_COMPLETED。

    940100

    c++11新特性之线程相关所有知识点

    函数将会阻塞主线程,直到线程函数执行结束,线程函数的返回值将会被忽略。...如果没有调用join或者detach函数,假如线程函数执行时间较长,此时线程对象的生命周期结束调用析构函数清理资源,这时可能会发生错误,这里有两种解决办法,一个是调用join(),保证线程函数的生命周期和线程对象的生命周期相同...,另一个是调用detach(),将线程和线程对象分离,这里需要注意,如果线程已经和对象分离,那我们就再也无法控制线程什么时候结束了,不能再通过join来等待线程执行完。...若从 std::async 获得的 std::future 未被移动或绑定到引用,则在完整表达式结尾, std::future的析构函数将阻塞直至异步计算完成,实际上相当于同步操作: std::async...• std::future用于异步调用的包装和返回值。 • async更方便的实现了异步调用,异步调用优先使用async取代创建线程。

    62520

    跟面试官刚同步异步编程,有她完全够用了

    但是一旦调用返回,就得到返回值了。 异步:程序在发出调用之后,这个调用就直接返回了,所有没有返回结果。而是在调用发出后,被调用者通过状态,通知调用者,或通过回调函数处理这个调用。...id和一个传入的字符串 分别在新起的线程和当前线程中调用他 auto fun = [](std::string a, std::mutex & lock) { //使用mutex的原因...,保证同一时刻只要一个线程可以访问,或者只要一个线程进行写操作。...(&X::foo, &x, 42, "Hello");//async是在新线程中异步执行 通过返回的future的get函数来取值 // Calls x.bar("world!")...对象 std::cout << "please wait"; std::chrono::milliseconds span(100);//主线程也可以使用wait_for等待结果返回 可设置超时时间

    56920

    泛函编程(18)-泛函库设计-并行运算组件库

    假设我们选择用由程序员调用一个函数来确定产生新线程。...并不改变pa,还是返回Par[A] 那么把一个运算放到一个新的线程里运行可以用这个函数表达: def async[A](a: => A): Par[A] = fork(unit(a)) //不需要了解任何关于...知道fork会为这个运算设定新的运行空间。注意还是返回Par[A] 因为我们追求的是线程机制和并行运算的松散耦合,那么我们就不会在Par里实际进行并行运算的运行,那么Par就只是对一个并行运算的描述。...返回的结果Par必须经run来运行并获取结果 3 def async[A](a: => A): Par[A] = fork(unit(a)) //不需要了解任何关于Par的信息。...如果我们再用这个Future的get来得取表达式的运算结果的话,这个运算是在当前主线程中运行的。async通过fork选择新的线程;并向新的运行环境提交了运算任务。

    69570

    来聊聊C++中头疼的线程、并发

    这个子线程就有运行时库负责清理相关线程的资源(守护线程)。一旦detach()调用后,就不能再用join()了。 joinable()判断是否可以成功使用join()或者detach()。...当前线程会一直被阻塞,直到另外一个线程在相同的std::condition_variable对象上调用了notification函数来唤醒当前线程。...希望线程返回一个结果 std::async是个函数模板,用来启动一个异步任务,它返回一个std::future对象,std::future是一个类模板.。...异步任务:自动创建一个线程并开始执行对应的线程入口函数,他返回一个std::future对象 这个future对象里面含有线程入口函数所返回的结果,我们可以通过调用future对象的成员函数get()来获取结果...,第二个参数作为线程入口函数的参数 t1.join(); std::future res=mypt.get_future(); //std::future对象里包含线程入口函数的返回结果

    5.1K41

    C++线程知识点汇总

    unsetunsetstd::threadunsetunset std::thread 是 C++11 标准库中用于创建和管理线程的类,它提供了一种简单的方式来启动新的线程并执行指定的函数或可调用对象。...下面是 std::thread 的主要特点和用法: 创建线程:使用 std::thread 类可以创建新的线程,并指定要执行的函数或可调用对象。...检查异步操作状态:可以通过 std::future 的成员函数 valid() 来检查与之关联的异步操作是否有效,以及 wait_for() 和 wait_until() 函数来检查异步操作的状态和等待一段时间...下面是 std::async 的主要特点和用法: 创建异步任务:std::async 函数用于创建一个异步任务,该任务会在后台线程中执行指定的函数,并返回一个与之关联的 std::future 对象,用于获取异步任务的结果...调用 std::future 对象的 get() 方法可以阻塞当前线程,直到异步任务执行完成并返回结果。

    16610

    学习C++,必须学习的线程知识点

    可以将函数或可调用对象作为参数传递给 std::thread 构造函数,以在新线程中执行该函数或可调用对象。...通常情况下,如果一个 std::thread 对象代表的线程还在运行,会调用 std::terminate 终止程序;如果线程已经结束,会释放线程的资源。...9、async std::async 是 C++ 标准库中提供的用于创建异步任务的函数,用于启动一个新的线程或者在线程池中执行指定的任务,并返回一个 std::future 对象,用于获取异步操作的结果...以下是 std::async 的一些重要特点和用法: 创建异步任务: std::async 可以用于创建异步任务,执行指定的函数或可调用对象,并返回一个 std::future 对象,用于获取任务的结果...返回值类型: std::async 返回一个 std::future 对象,用于获取异步任务的结果。

    32910

    python多任务—协程(一)

    ) # task 是 Future的子类 True 补:isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。...从下例可以看出,coroutine执行结束时候会调用回调函数,并通过future获取协程返回(return)的结果。我们创建的task和回调里面的future对象,实际上是同一个对象。...如果调用partial对象时提供了更多的参数,那么他们会被添加到args的后面,如果提供了更多的关键字参数,那么它们将扩展或者覆盖已经冻结的关键字参数。...它必须为以下常数之一: FIRST_COMPLETED 函数将在任意可等待对象结束或取消时返回。 FIRST_EXCEPTION 函数将在任意可等待对象因引发异常而结束时返回。...ALL_COMPLETED 函数将在所有可等待对象结束或取消时返回。 与 wait_for() 不同,wait() 在超时发生时不会取消可等待对象。

    1.5K20

    如何在 Spring 异步调用中传递上下文什么是异步调用?

    通过在方法或类上设置 @Async注解,可使得方法被异步调用。调用者会在调用时立即返回,而被调用方法的实际执行是交给 Spring 的 TaskExecutor 来完成的。...所以被注解的方法被调用的时候,会在新的线程中执行,而调用它的方法会在原线程中执行,这样可以避免阻塞,以及保证任务的实时性。...可以看到 TaskService 中的三个方法是异步执行的,接口的结果快速返回,日志信息异步输出。异步调用,通过开启新的线程调用的方法,不影响主线程。...CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行。...装饰模式是动态的给一个对象添加一些额外的功能,就增加功能来说,装饰模式比生成子类更为灵活。因此 TaskDecorator 主要用于任务的调用时设置一些执行上下文,或者为任务执行提供一些监视/统计。

    2.1K30

    如何在 Spring 异步调用中传递上下文

    通过在方法或类上设置 @Async注解,可使得方法被异步调用。调用者会在调用时立即返回,而被调用方法的实际执行是交给 Spring 的 TaskExecutor 来完成的。...所以被注解的方法被调用的时候,会在新的线程中执行,而调用它的方法会在原线程中执行,这样可以避免阻塞,以及保证任务的实时性。...可以看到 TaskService 中的三个方法是异步执行的,接口的结果快速返回,日志信息异步输出。异步调用,通过开启新的线程调用的方法,不影响主线程。...CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行。...装饰模式是动态的给一个对象添加一些额外的功能,就增加功能来说,装饰模式比生成子类更为灵活。因此 TaskDecorator 主要用于任务的调用时设置一些执行上下文,或者为任务执行提供一些监视/统计。

    3.3K30
    领券