Как синхронизировать статическое поле в C ++ - PullRequest
1 голос
/ 30 апреля 2019

Я хочу иметь объекты с разными идентификаторами, когда они инициализируются. Например, предположим, у меня есть класс с именем «Объект»

public class Object {
   public:
      int id;
      static int tmp;
      Object() {
          id = tmp++;
      }
}

int Object::tmp = 0;

По сути, я хочу присвоить уникальные идентификаторы объектам, инициализированным из класса Object, увеличив значение статического поля tmp. Это должно работать, когда есть только один поток. Но что я должен сделать для синхронизации статического поля tmp, когда есть несколько потоков, в которых Object может быть инициализирован.

1 Ответ

1 голос
/ 30 апреля 2019

Но что мне делать, чтобы синхронизировать статическое поле tmp, когда есть несколько потоков, в которых можно инициализировать объект.

Вы должны использовать std::atomic<unsigned> для счетчика, чтобы сделать приращениеэто потокобезопасно.unsigned, чтобы гарантировать, что оборачивание счетчика не приведет к неопределенному поведению.

class Object {
    static std::atomic<unsigned> tmp;
public:
    unsigned const id = tmp.fetch_add(1, std::memory_order_relaxed);
};

std::atomic<unsigned> Object::tmp{0};

Обратите внимание, что инициализация Object::tmp происходит на статической фазе инициализации перед динамикой инициализация вызывает любой конструктор любого глобального объекта.


Более эффективная стратегия состоит в использовании специфичных для потока счетчиков, чтобы потоки не конкурировали при увеличении общего счетчика.

...