简体   繁体   English

Static 共享 *.so 文件的对象

[英]Static objects for shared *.so files

In C++ project, we have the following dependency:在 C++ 项目中,我们有以下依赖:

  1. Package1.so - shared lib/functional having std::shared_ptr<T > getInstance() * static function which returns a static shared pointer. Package1.so - 具有std::shared_ptr<T > getInstance() * static function 的共享库/函数,它返回一个 static 共享指针。 If the static pointer isn't initialized, it initializes then returns the pointer.如果 static 指针未初始化,它会初始化然后返回指针。 It also uses static mutex to guarantee sync in case of MT mode call to getInstance它还使用 static 互斥体来保证 MT 模式调用 getInstance 时的同步

  2. Package2, which depends on Package1.so and uses the getInstance function to fetch data Package2,依赖Package1.so,使用getInstance function 获取数据

  3. Package3, has dependency from Package1 and Package2 and also directly uses 'getInstance' function Package3,依赖于 Package1 和 Package2,也直接使用 'getInstance' function

It's expected that static object should be created only once and be shared between package 2& 3预计 static object 应该只创建一次并在 package 2& 3 之间共享

However, seems the shared object is different for Package2 & 3 -> the object is created twice.但是,似乎共享的 object 对于 Package2 & 3 是不同的 -> object 创建了两次。

Question: Is static memory space is not shared in case of.so files?问题:static memory空间是不是在.so文件的情况下不共享?

// Package 1
// h1.hpp
#pragma once

class A {
public:
  static std::shared_ptr<A> get_instance();
  
 private:
  static std::mutex m_mtx;
  static std::shared_ptr<A> m_instance;
};

// Package 1
// h1.cpp
static std::mutex A::m_mtx;
static std::shared_ptr<A> A::m_instance;

std::shared_ptr<A> A::get_instance() {
  const std::lock_guard<std::mutex> lck{m_mtx);
  if (nullptr == m_instance) {
     m_instance = std::make_shared<A>();
  }
  return m_instance;
}


// Package 2 depending Package 1
#include <path/h1.hpp>

void f() {
   auto instance = A::get_instance(); // for first call creates new
}


// Package 3 depending Package 1 and Package 2
#include <path/h1.hpp>
void g() {
   auto instance = A::get_instance(); // for first call creates new
}



// Result - 2 instances are created of A - one thought Package 3 one through Package 2

// Expected - a single A should be created and static shared ptr should be shared. // 预期 - 应该创建单个 A 并且应该共享 static 共享指针。

This is expected.这是预期的。

The shared pointers themselves are different because they are different objects but they point to the same underlying object. This is by design.共享指针本身是不同的,因为它们是不同的对象,但它们指向相同的底层 object。这是设计使然。

I took your example and reran it, it produces the following.我拿了你的例子并重新运行它,它产生了以下内容。

$ ./main
Instance:0x7fb7001a00a0 Object:0x55ae9c53aec0
Instance:0x7fb70019b0a0 Object:0x55ae9c53aec0

I created a main.cpp that calls f and g我创建了一个调用fg的 main.cpp

void f();
void g();

int main() {
        f();
        g();
}

f.cpp is in a different library libf.so . f.cpp在不同的库libf.so中。 I assign it to a static object otherwise calling f() and g() could print the same address for same objects just by coincidence.我将它分配给 static object 否则调用f()g()可能会巧合地为相同的对象打印相同的地址。

#include "h1.h"
void f() {
   static auto instance = A::get_instance(); // for first call creates new
   printf( "Instance:%p Object:%p\n", &instance, instance.get() );
}

Same thing for g.cpp g.cpp

#include "h1.h"
void g() {
   static auto instance = A::get_instance(); // for first call creates new
   printf( "Instance:%p Object:%p\n", &instance, instance.get() );
}

Notice that on h1.h you are returning a copy of the static variable, not a reference to it.请注意,在h1.h上,您返回的是 static 变量的副本,而不是对它的引用。 That is okay but it will generate a copy and perhaps that's not what you expect.没关系,但它会生成一个副本,也许这不是您所期望的。

#pragma once

#include <memory>
#include <mutex>

class A {
public:
  static std::shared_ptr<A> get_instance();
private:
  static std::mutex m_mtx;
  static std::shared_ptr<A> m_instance;
};

On this file h1.cpp you had the keyword static prefixed to the implementation of the two variables.在此文件h1.cpp ,您将关键字static作为两个变量实现的前缀。 That is a bug and I commented out.那是一个错误,我注释掉了。 It should not compile.它不应该编译。 Maybe that is the reason for your problem.也许这就是您遇到问题的原因。

#include "h1.h"

/* static */  std::mutex A::m_mtx;
/* static */  std::shared_ptr<A> A::m_instance;

std::shared_ptr<A> A::get_instance() {
  const std::lock_guard<std::mutex> lck{m_mtx};
  if (nullptr == m_instance) {
     m_instance = std::make_shared<A>();
  }
  return m_instance;
}

CMakeLists.txt CMakeLists.txt

cmake_minimum_required( VERSION 3.0 )
project(deps)

add_library( h1 SHARED h1.cpp )

add_library( f SHARED f.cpp )
target_link_libraries( f h1 )

add_library( g SHARED g.cpp )
target_link_libraries( g h1 )

add_executable( main main.cpp )
target_link_libraries( main h1 f g )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM