假设我正在启动a std::thread
然后detach()
它,所以线程继续执行,即使std::thread
它曾经表示它,超出范围.
进一步假设该程序不具有用于接合分离的线程一个可靠的协议1,所以分离线程仍然运行时main()
退出.
我在标准中找不到任何东西(更准确地说,在N3797 C++ 14草案中),它描述了应该发生的事情,1.10和30.3都没有包含相关的措辞.
1另一个可能是等同的问题是:"可以再次连接一个分离的线程",因为你要发明加入的协议,信号部分必须在线程仍在运行时完成,并且OS调度程序可能决定在执行信令之后让线程休眠一小时,接收端无法可靠地检测到线程实际完成.
如果用完main()
了卸下运行的线程是不确定的行为,那么任何使用的std::thread::detach()
是除非主线程永远不会退出未定义行为2.
因此,运行main()
脱离线程的耗尽必须具有已定义的效果.问题是:其中(在C++标准,不POSIX,不OS文档,......)都处于所定义的那些的效果.
2分离的线程不能加入(在感std::thread::join()
).您可以等待分离线程的结果(例如,通过未来std::packaged_task
,或通过计数信号量或标志和条件变量),但这并不能保证线程已完成执行.事实上,除非你把信令部分进入线程的第一个自动对象的析构函数,也将在一般情况下,是运行的代码(析构函数)后的信号代码.如果操作系统安排主线程使用结果并在分离的线程完成运行所述析构函数之前退出,^ Wis定义会发生什么?
有时我必须使用它std::thread
来加速我的应用程序.我也知道join()
等待线程完成.这很容易理解,但是呼叫detach()
和不呼叫之间的区别是什么?
我认为没有detach()
,线程的方法将独立使用线程.
不分离:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called without detach");
});
//some code here
}
Run Code Online (Sandbox Code Playgroud)
呼叫分离:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called with detach");
});
t.detach();
//some code here
}
Run Code Online (Sandbox Code Playgroud) 相关问题:
关于C++ 11:
关于Boost:
我如何获得一个线程池,以任务发送到,而无需创建和删除它们一遍又一遍?这意味着要在不加入的情况下重新同步的持久线程.
我的代码看起来像这样:
namespace {
std::vector<std::thread> workers;
int total = 4;
int arr[4] = {0};
void each_thread_does(int i) {
arr[i] += 2;
}
}
int main(int argc, char *argv[]) {
for (int i = 0; i < 8; ++i) { // for 8 iterations,
for (int j = 0; j < 4; ++j) {
workers.push_back(std::thread(each_thread_does, j));
}
for (std::thread &t: …
Run Code Online (Sandbox Code Playgroud) 如何检查a std::thread
是否仍在运行(以独立于平台的方式)?它缺乏一种timed_join()
方法,joinable()
并不适用于此.
我想std::lock_guard
在线程中使用a锁定互斥锁并使用try_lock()
互斥锁的方法来确定它是否仍然被锁定(线程正在运行),但对我来说似乎不必要的复杂.
你知道更优雅的方法吗?
更新:要明确:我想检查线程是否干净地退出.为此,"悬挂"线程被认为正在运行.
在后C++ 11世界中设置std :: thread实例优先级的正确方法是什么
是否有一种可移植的方式,至少在Windows和POSIX(Linux)环境中有效?
或者是获取句柄并使用特定操作系统可用的本机调用的问题?
为什么在创建时不能通过引用传递对象std::thread
?
例如,以下snippit给出了编译错误:
#include <iostream>
#include <thread>
using namespace std;
static void SimpleThread(int& a) // compile error
//static void SimpleThread(int a) // OK
{
cout << __PRETTY_FUNCTION__ << ":" << a << endl;
}
int main()
{
int a = 6;
auto thread1 = std::thread(SimpleThread, a);
thread1.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:
In file included from /usr/include/c++/4.8/thread:39:0,
from ./std_thread_refs.cpp:5:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<void (*(int))(int&)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}]’ …
Run Code Online (Sandbox Code Playgroud) 在C++ 03中,我使用pthread和自建的线程池,它总是保持几个线程运行(因为pthread_create
速度很慢),这样我就可以在不考虑性能问题的情况下为小任务启动线程.
现在,在C++ 11中我们有std::thread
.我想标准没有说明具体的实现,所以我的问题是标准的库实现.他们是否通常选择合并方法来构造std::thread
s是便宜的(例如不调用pthread_create
posix),或者std::thread
只是一个包装器?
换句话说,是否仍然在C++ 11中推荐一个线程池,或者我应该只std::thread
在需要时创建一个并将性能提升到标准库?
这是一个例子:
#include<iostream>
#include<thread>
using namespace std;
void f1(double& ret) {
ret=5.;
}
void f2(double* ret) {
*ret=5.;
}
int main() {
double ret=0.;
thread t1(f1, ret);
t1.join();
cout << "ret=" << ret << endl;
thread t2(f2, &ret);
t2.join();
cout << "ret=" << ret << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
ret=0
ret=5
Run Code Online (Sandbox Code Playgroud)
用gcc 4.5.2编译,有和没有-O2
标志.
这是预期的行为吗?
这个节目数据是否免费比赛?
谢谢
我最近实现线程/互斥管理器的努力最终导致75%的CPU负载(4核心),而所有四个正在运行的线程都处于睡眠状态或等待互斥锁解锁.
具体的类太大了,不能完全发布在这里,但我可以把原因缩小到两个互斥锁的死锁安全获取
std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock );
std::unique_lock<std::mutex> lock2( mutex2, std::defer_lock );
std::lock( lock1, lock2 );
Run Code Online (Sandbox Code Playgroud)
该类的另一部分使用std::condition_variable
with wait()
和notify_one()
on mutex1
来同时有选择地执行某些代码.
简单的改变
std::unique_lock<std::mutex> lock1( mutex1 );
std::unique_lock<std::mutex> lock2( mutex2 );
Run Code Online (Sandbox Code Playgroud)
使CPU使用率降至正常的1-2%.
我不敢相信,std::lock()
功能是低效的.这可能是g ++ 4.6.3中的错误吗?
编辑:(示例)
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mutex1, mutex2;
std::condition_variable cond_var;
bool cond = false;
std::atomic<bool>done{false};
using namespace std::chrono_literals;
void Take_Locks()
{
while( !done )
{
std::this_thread::sleep_for( 1s );
std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock …
Run Code Online (Sandbox Code Playgroud) 我对这个std::async
功能有点困惑.
规范说:正在执行的异步操作"好像在新的执行线程中"(C++11§30.6.8/ 11).
现在,这意味着什么?
在我的理解中,代码
std::future<double> fut = std::async(std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)
应该pow2
在新线程上启动函数并将值传递num
给线程的值,然后在将来某个时候,当函数完成时,将结果放入fut
(只要函数pow2
具有类似的签名double pow2(double);
).但规范说"似乎",这使得整个事情对我来说有点模糊.
问题是:
在这种情况下是否始终启动新线程?希望如此.我的意思是对我来说,参数std::launch::async
是有意义的,我明确说明我确实想要创建一个新线程.
和代码
std::future<double> fut = std::async(std::launch::deferred, pow2, num);
Run Code Online (Sandbox Code Playgroud)
应该通过将函数调用延迟到我写的类似的点来使延迟评估成为可能.在这种情况下,参数,应该意味着我明确说明,我不想要一个新线程,我只是想确保在需要它的返回值时调用该函数.pow2
var = fut.get();
std::launch::deferred
我的假设是否正确?如果没有,请解释.
另外,我知道默认情况下该函数调用如下:
std::future<double> fut = std::async(std::launch::deferred | std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我被告知是否将启动新线程取决于实现.那又是什么意思呢?
c++ ×10
c++11 ×10
stdthread ×10
exit ×1
future ×1
mutex ×1
portability ×1
reference ×1
threadpool ×1