假设我们有一个全局变量和一个全局非成员函数。
int GlobalVariable = 0;
void GlobalFunction();
Run Code Online (Sandbox Code Playgroud)
我们有
std::mutex MutexObject;
Run Code Online (Sandbox Code Playgroud)
然后在其中一个线程中,我们有这样的代码块:
{
std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
Run Code Online (Sandbox Code Playgroud)
现在,在另一个并行运行的线程中,如果我们这样做会发生什么:
{
//std::lock_guard<std::mutex> lock(MutexObject);
GlobalVairable++;
GlobalFunction()
}
Run Code Online (Sandbox Code Playgroud)
所以问题是,互斥体是否在被另一个线程拥有时只锁定自己,而不关心在关键代码中尝试访问的内容?或者编译器,或者在运行时,操作系统实际上指定了关键代码中正在访问的内存位置,目前被 MutexObject 阻止?
我的猜测是前者,但我需要听听经验丰富的程序员的意见;感谢您花时间阅读我的问题。
我对学习编程语言比较陌生,我觉得我对面向对象编程语言的理解有 20% 到 25%,更具体地说是 C# 语言。所以我真的提出了这个问题,但我不知道它的答案对我学习语言的过程的实际意义(如果有的话),但我真的觉得我有必要提出这个问题。
当一个方法被调用执行时,我知道它的所有局部变量及其参数和返回值实际上都存在于堆栈内存中。而方法本身作为实例化对象或静态类的成员,或作为非静态类的静态成员从堆内存中调用。
现在我的问题是,当该方法被调用到堆栈中时,是只有变量和参数将存在于堆栈中,还是整个方法及其所有代码块都将存在于堆栈中时刻(执行)?
此查询源自对实例化方法(或静态方法)内的代码块性质的类似比较,当该方法被调用时和未被调用时,与成员的性质相比非静态类,而类被实例化为对象,而不是。
现在,非静态类的成员被认为是一个蓝图,即它们以不可接近且无功能的形式存在(不能调用字段和方法,不能更改字段的值,方法不能改变值),但是这个蓝图可以实例化为一个具有其成员的具体功能对象。
现在,如果堆中实例化方法内的代码块只不过是一个蓝图,当方法被调用时,该蓝图实际上会在堆栈中“实例化”,以执行它们在堆栈中的任务,然后被删除任务完成时的堆栈。在这里,栈可以被看作是程序实际执行的地方,而另一方面,堆中的所有东西,包括静态类和对象以及堆本身,都将被看作仅仅是数据和指令的存储位置。不时借用和利用堆栈,堆栈实际上执行了我们整个程序的任务。
但是,如果堆栈内存实际上并不包含正在执行的方法的代码,并且堆栈只获取方法局部变量和参数的临时值,而方法本身在堆中并同时执行编码来自其堆位置的指令,仅将值借给进程中的堆栈。这里的堆栈看起来只是一个变量的值持有者,而对象和静态类及其方法是程序的实际执行者,它们在堆本身中,并且一个实例化的方法(或静态方法)及其代码具体存在并在堆中运行。
第三种可能性是两个内存(堆栈和堆)都不是代码执行的实际位置,而是在处理器本身的某个地方发生数据的执行和更改,堆和堆栈都只是存储位置对于在接受、保存和清理数据和指令方面的不同使用模式,仅此而已。
很抱歉问了这么长的问题,我不知道对我作为程序员的回答有多大帮助,但这确实让我头疼了几天,我在文本中找不到答案是为初学者设计的,所以我真的不知所措!
我对C++编程和编程本身比较陌生,我试图熟悉C++代码的Visual Studio编译器的预期行为.(Visual Studio 2015)
class aClass {
public:
int a;
int b;
}
Run Code Online (Sandbox Code Playgroud)
然后在函数块内部,当我声明这个类的对象时:
aClass obj;
cout << obj.a;
Run Code Online (Sandbox Code Playgroud)
然后我确实有一次获得随机RAM内容作为变量的值,而有时我得到编译错误:局部变量未初始化.(值得注意的是,每当编译器克服错误一次,它就不会再次重复它,尽管它可能会在第一次克服错误之前多次重复它!)
关于声明对象的最佳实践的任何建议,
我应该坚持使用表格aClass obj = aClass();来获得一致的结果.
或任何相关的意见.提前致谢.
我知道 #inclusion 通常被描述为文本复制粘贴预处理器指令。现在,如果标头受到 #include 保护或 #pragma 一次,那么我们如何描述第一个翻译单元之后实际发生的情况到 #include 所述标头?