问题标签 [stdthread]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
7 回答
67427 浏览

c++ - 当 main() 退出时,分离的线程会发生什么?

假设我开始 astd::thread然后detach()它,所以线程继续执行,即使std::thread曾经代表它,超出范围。

进一步假设程序没有可靠的协议来加入分离线程1main() ,因此分离线程在退出时仍然运行。

我在标准中找不到任何东西(更准确地说,在 N3797 C++14 草案中),它描述了应该发生的事情,1.10 和 30.3 都没有包含相关的措辞。

1另一个可能等效的问题是:“可以再次加入分离的线程吗”,因为无论您发明什么协议来加入,信号部分都必须在线程仍在运行时完成,并且操作系统调度程序可能决定在执行信号后立即让线程休眠一个小时,而接收端无法可靠地检测到线程实际上已完成。

如果在运行main()分离线程时用完是未定义的行为,那么任何使用 ofstd::thread::detach()都是未定义的行为,除非主线程永远不会退出2

因此,运行main()分离线程的用完必须具有定义的效果。问题是:在哪里(在C++ 标准中,不是 POSIX,不是 OS 文档,......)是那些定义的效果。

2无法连接分离的线程(在 的意义上std::thread::join())。您可以等待来自分离线程的结果(例如,通过来自 的未来std::packaged_task,或通过计数信号量或标志和条件变量),但这并不能保证线程已完成执行。实际上,除非您将信号部分放入线程的第一个自动对象的析构函数中,否则通常会有代码(析构函数)在信号代码之后运行。如果操作系统安排主线程在分离线程完成运行所述析构函数之前使用结果并退出,那么^Wi 定义会发生什么?

0 投票
1 回答
801 浏览

c++ - std::thread 构造函数(变量数量)

您好,我的程序有一点问题(我想将数组乘以标量)。

基本上我想创建一个线程向量来执行乘法人员(逐个元素)

代码示例

第一个main实现函数

}

now 实现标量乘法的函数

}

我还没有实现这部分,但我无法解决一个问题

在行

编译器说那里有问题

“错误:没有构造函数实例 std::thread::thread 与参数列表匹配”。

我似乎无法解决这个问题。我确实读过我应该通过引用将变量传递给线程构造函数中的函数,所以我认为这不是问题。我将 6 个变量传递给乘法函数,所以它应该没问题,但它不是,我不知道在这里做什么......谷歌也无法帮助我,因为我搜索了类似的问题。

提前感谢您的帮助。

0 投票
1 回答
2259 浏览

c++ - 正确的线程调用语法?错误:没有匹配的调用 std::thread::thread()

0 投票
2 回答
14623 浏览

c++ - 等待 std::thread 完成

我正在尝试在程序终止时优雅地进行清理,所以我呼吁join()astd::thread等待它完成。这似乎永远阻塞了主线程,但我不明白为什么,因为工作线程是一个(几乎)空循环,如下所示:

当然,我在ingrun之前设置为 false 。join现在,我怀疑它与它是一个成员函数并被调用 object destroy有关。我正在创建这样的线程:runThread.reset(new thread(&GameLoop::Run, this));, where runThreadisunique_ptr<std::thread>GameLoop. join()调用来自对象的析构函数GameLoop

如果它的对象正在被销毁,循环线程可能无法完成?根据调试器,循环线程在msvcr120d.dll. 如果是这样,你会如何处理?

当心:新来std::thread这里!

更新:这是我加入析构函数的呼吁:

更新2:如果我删除join()我得到一个异常~thread()

0 投票
3 回答
6135 浏览

c++ - 在 C++11 中的 std::thread 退出时自动调用函数

我想设置一个函数(或 lambda 函数)的调用以在当前线程退出时自动发生,但我看不到任何可行的方法,std::thread除非我接管线程创建的整个任务或手动确保每个线程都会调用一些我总是提供的特定函数作为它的最后一个操作。

本质上,我想要其原型可能类似于以下内容的函数:

它将执行任何必要的设置,以确保在调用 on_thread_exit 的线程最终终止时自动调用给定函数,并且不需要在线程创建或终止时显式调用任何特定函数。

0 投票
1 回答
765 浏览

c++ - 创建新线程时复制构造函数调用

我正在阅读 C++ Concurrency in Action 一书,以了解有关线程和 C++ 内存模块的更多信息。我很好奇复制构造函数在以下代码中被调用的次数:

当我在 Visual Studio 2013 调试器中浏览这段代码时,我看到复制构造函数被调用了四次。从主线程调用它三次,然后从新线程调用一次。我期待一个,因为它为新线程制作了对象的副本。为什么要创建三个额外的副本?

0 投票
2 回答
422 浏览

c++ - 如果 mutex::lock() 已被另一个线程锁定,它多久检查一次解锁状态?

根据cppreferencestd::lock_guard ,使用参数构造 an会std::mutex调用lock()that 的方法mutex

根据cplusplus,关于mutex'slock()方法:

如果互斥锁被另一个线程锁定,则调用线程的执行将被阻塞,直到被另一个线程解锁...

我不确定名义上的问题是否措辞正确,因此我将其放在以下代码的上下文中。

我想对此进行测试,看看调用线程是否真的在等待解锁,而不是终止其可调用对象(例如函数、仿函数、lambda)的执行和/或抛出异常。下面的代码有两个线程t1t2每个线程都有一个指向同一个函数的指针foo。在执行锁保护代码之前,每次调用foo都会sleep_for有一定的时间,由foounsigned参数决定。num锁保护代码本身包含另一个sleep_for周期,以使任何阻塞的执行周期更加明显:

控制台输出:

输出大约/至少需要 3.05 秒5。输出需要大约/至少额外 3 秒10。这意味着t2首先执行受保护的代码,因为它在锁定mutex.

我假设一旦对foofrom 线程的调用t1到达该lock_guard行并发现mutex已经被 锁定t2t1不会终止执行或引发异常。t1只是等待它被解锁。

多久检查一次解锁std::mutex::lock()std::lock_guard支票有多贵?检查是否执行如下?

0 投票
2 回答
18809 浏览

c++ - std::thread 通过引用传递调用复制构造函数

好吧,我在使用 std::thread 将数据传递到线程时遇到了问题。我以为我理解了复制构造函数等的一般语义,但似乎我不太明白这个问题。我有一个名为 Log 的简单类,它因此隐藏了它的复制构造函数:

现在我有一个主要基于http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_server.cpp

可以看到 main 调用了函数 server 并传递了 IOService、portNumber 和 logger。记录器通过引用传递,因此:

当我尝试通过引用将记录器(或套接字)传递给线程时出现编译器错误,但在通过引用将其传递给 session() 时没有收到错误

现在我认为我正确理解了引用与传递指针相同。也就是说,它不调用复制构造函数,它只是传递指针,它让您在语法上将其视为不是指针。

错误 C2248:“Log::Log”:无法访问在“Log”类中声明的私有成员

1> \log.h(55) : 见 'Log::Log' 的声明

1> \log.h(28) : 见“日志”声明

...

:请参阅正在编译的函数模板实例化 'std::thread::thread(_Fn,_V0_t &&,_V1_t)' 的参考

1> 与

1> [

1> Fn=void ( _cdecl *)(boost::asio::ip::tcp::socket *,Log &),

1> _V0_t=boost::asio::ip::tcp::socket *,

1> _V1_t=日志&

1>]

但是,如果我修改它以传递一个指针,一切都很开心

为什么通过引用传递调用我的复制构造函数。由于std::thread,这里发生了什么特别的事情吗?我是否误解了复制构造函数并通过引用传递?

如果我尝试像示例中那样使用 std::move() ,我会得到一个不同但同样令人困惑的错误。是否有可能我的 VS2012 没有正确实现 C++11?

0 投票
1 回答
1384 浏览

c++ - std::mutex 锁定的顺序

我很少考虑在两个连续的表达式之间,在调用函数和执行其主体的第一个表达式之间,或者在调用构造函数和执行其初始化程序之间会发生什么。然后我开始阅读并发......

std::thread1.) 在对具有相同可调用对象(例如函数、函子、lambda)的构造函数的两次连续调用中,其主体以使用std::lock_guard相同std::mutex对象的初始化开始,标准是否保证对应于第一个thread构造函数调用的线程执行锁-首先是受保护的代码?

2.)如果标准没有做出保证,那么第二个thread构造函数调用对应的线程是否有任何理论上或实际的可能性首先执行受保护的代码?(例如,在执行初始化程序或第一个thread构造函数调用的主体期间,系统负载很重)

这是一个全局std::mutex对象m和一个unsigned num初始化为1. 函数foo主体的左大括号{std::lock_guard. 在main中,有两个std::threadst1t2t1首先调用线程构造函数。t2第二次调用线程构造函数。每个线程都由一个指向foo. 带参数的t1调用。带参数的调用。根据哪个线程锁定第一个,在两个线程都执行了锁保护代码之后,' 的值将是 a或 a 。将等于foounsigned1t2foounsigned2mutexnum43num4如果t1击败t2锁定。否则,num将等于3。通过循环并在每个循环结束时重置num为,我对此进行了 100,000 次试验。1(据我所知,结果不也不应该取决于join()首先编辑哪个线程。)

最后,countequals 100000,所以t1每次都赢得比赛。但这些试验并不能证明什么。

3.) 标准要求“首先调用thread构造函数”是否总是意味着“首先调用传递给thread构造函数的可调用对象”?

4.) 标准要求“首先调用传递给thread构造函数的可调用对象”是否总是意味着“首先锁定mutex”;假设在可调用的主体中,不存在依赖于在std::lock_guard初始化行之前传递给可调用的参数的代码吗?(还排除任何可调用的局部static变量,例如调用次数计数器,可用于故意延迟某些调用。)

0 投票
3 回答
3348 浏览

c++ - 如何匿名声明 std::thread ?

考虑以下短程序:

这编译并运行(永远),与

在注释掉的行中,我正在尝试使用此处描述的技术来匿名声明一个新线程。但是,当该行被重新注释时,我可以编译但运行会出现以下错误:

我怎样才能正确地匿名声明一个线程?

注意,我在g++ 4.4.7