我想在某个地方有一个答案,但我找不到它,因为有很多线程问题,相比之下,我的相当简单.
我不是要创建线程安全的副本或赋值构造函数或类似的东西.
我想知道的是,如果我有一个表示互斥锁的类,并且我从一个实例化它的函数返回,这首先发生,我的互斥体的析构函数(因此解锁它)或返回值的复制构造函数.这是我的例子:
string blah::get_data(void)
{
MutexLock ml(shared_somewhere_else); // so this locks two threads from calling get_data at the same time
string x = "return data";
return x;
}
Run Code Online (Sandbox Code Playgroud)
在其他地方,我们称之为get_data ...
string result = get_data();
Run Code Online (Sandbox Code Playgroud)
回想一下C,我们永远不会返回指向全局变量的指针,因为返回后局部变量超出了范围.
C++没有这个问题,因为x会被复制到结果中.我想知道的是什么时候发生.在复制之前我的锁是免费的吗?
在这个简单的例子中,"返回数据"是静态信息,但我正在使用它,它的数据可以由另一个线程更改(也锁定在同一个MutexLock上),所以如果锁在释放之前释放了复制到结果制作,副本可能会被破坏.
我不确定我是否正在解释这个问题,所以我会试着澄清这是否有意义.
在尝试编写一个类,调用它的构造函数和析构函数之间的持续时间时,我遇到了我认为是clang中的错误.(编辑:这不是一个bug;它是实现定义的副本省略)
timer下面的结构保存一个指向作为引用传入的持续时间对象的指针,并将范围的持续时间添加到此.
#include <iostream>
#include <chrono>
struct timer {
using clock = std::chrono::high_resolution_clock;
using time_point = clock::time_point;
using duration = clock::duration;
duration* d_;
time_point start_;
timer(duration &d) : d_(&d), start_(clock::now()) {}
~timer(){
auto duration = clock::now() - start_;
*d_ += duration;
std::cerr << "duration: " << duration.count() << std::endl;
}
};
timer::duration f(){
timer::duration d{};
timer _(d);
std::cerr << "some heavy calculation here" << std::endl;
return d;
}
int main(){
std::cout << "function: " << f().count() << std::endl;
} …Run Code Online (Sandbox Code Playgroud)