当前位置: 首页 > 知识库问答 >
问题:

为什么`std::promise::set_value`在从主线程调用时抛出错误?

许寒
2023-03-14

当我运行以下代码时,

#include <future>

int main()
{
    std::promise<int> p;
    p.set_value(1);
    return 0;
}

抛出std::system_error。但是,当我在另一个线程中设置Promission的值时,

#include <future>
#include <thread>

int main()
{
    std::promise<int> p;
    std::thread([&]{p.set_value(1);}).join();
    return 0;
}

一切正常。根据我对std::promise的理解,调用set_value不应该抛出异常,除非promise没有共享状态(即它已从其中移动)或已经为其赋值,即使这样,它也会抛出std::future_error,而不是std::system_error。由于不存在数据竞争或任何类似的情况,因此无论我是从创建promise的线程还是在另一个线程中调用set_value都不重要。是不是我漏了什么?

我使用g++和clang都尝试了这一点,结果是相同的。具体地说,当我运行顶部的代码时,以下内容被输出到stderr:

terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)

这些命令用于编译顶部的代码,

g++ main_thread.cpp -o main_thread -std=c++17 -g -Og
clang main_thread.cpp -o main_thread -std=c++17 -lstdc++++

这些代码用于编译底部的代码:

g++ separate_thread.cpp -o separate_thread -lpthread -std=c++17 -g -Og
clang separate_thread.cpp -o separate_thread -std=c++17 -lstdc++ -lpthread

共有1个答案

单于俊智
2023-03-14

std::promise是线程支持库的一部分,因此它需要在编译器选项(例如-pthread)中启用线程支持。

 类似资料:
  • 问题内容: ConcurrentModificationException:当不允许对对象进行并发修改时,检测到该对象的并发修改的方法可能会抛出此异常。 上面是javadoc中的ConcurrentModificationException定义。 所以我尝试测试以下代码: 代码很简单。10个线程从arraylist对象中删除该元素。确保多个线程访问一个对象。但它运行正常。没有异常被抛出。为什么?

  • 问题内容: 这可能是一个愚蠢的问题,但是我正在测试我对Python的一些假设,并对为什么以下代码段在线程中调用时不退出而在主线程中调用时退出而感到困惑。 sys.exit()的文档指出,该调用应从Python退出。从该程序的输出中可以看到,“ post thread exit”从不打印,但是即使在线程调用退出之后,主线程仍继续运行。 是否为每个线程创建了一个单独的解释器实例,并且对exit()的调

  • 我得到而调用 Java语言lang.StackOverflowerr:org处为null。阿帕奇。平民登录中。日志适配器$Slf4jLog。isDebugEnabled(LogAdapter.java:300)~[spring-jcl-5.1.10.RELEASE.jar:5.1.10.RELEASE]位于org。springframework。安全身份验证。ProviderManager。在or

  • 我的应用程序使用spring会话(与Redis)。而且我使用自定义登录控制器,因为我使用的是外部React客户端,而不是默认的spring登录页面。 登录控制器: 安全配置: 所以...endpoint的工作是正确的。但endpoint工作不正确。当调用时,它返回JSON: 下面是我在postman:中使用的请求 Cookie和会话都被删除了,也就是说logout的工作是正确的,但是为什么它会返回

  • 来自文档:http://docs.python.org/2/library/thread 让我们在这里只讨论非守护进程线程。因为第一个引号没有特别提到非守护进程线程,所以我假设,如果主线程退出,即使是非守护进程线程也应该被杀死。然而,第二句引文却表明了另一种情况。事实上,当主线程退出时,非守护进程线程确实不会被杀死。那么,这里的第一个引用有什么意义呢?

  • 我有一个在退出std::线程时执行回调函数的要求,该回调函数应该在主线程上执行。 在创建线程时,我需要分离线程,不能阻止线程完成的主循环执行。 我尝试使用std::signal,但它似乎没有在主线程上执行回调函数