Защита экземпляров класса от многопоточного доступа - PullRequest
1 голос
/ 30 января 2011

У меня есть класс C ++ со многими экземплярами, и я хочу, чтобы мой поток приложений был безопасным. Этот класс имеет член и функцию, которая его обрабатывает, например:

class MyCls {
  int x;
  void f() { x++; }
};

Мне нужно защитить этого участника, поэтому, насколько я вижу, у меня есть 2 варианта:

  1. Добавить глобальный критический раздел и введите его, прежде чем прикасаться к этому участнику.
  2. Добавить критический раздел в класс поэтому каждый экземпляр будет защищать своего члена.

Оба решения являются огромным перегибом:

  1. Два разных экземпляра вообще не должны синхронизироваться.
  2. Операционная система должна обрабатывать миллионы критических секций, где на самом деле очень мало коллизий.

Можно ли использовать другое решение или шаблоны многопоточного дизайна?

Ответы [ 4 ]

2 голосов
/ 30 января 2011

Не уверен, но я думаю, что проблему можно решить с помощью механизма Программная транзакционная память . Существует множество реализаций для C ++ .

1 голос
/ 30 января 2011

Что касается вашего первого беспокойства, у каждого экземпляра должен быть мьютекс члена, чтобы обеспечить отдельный критический раздел для каждого.

Что касается второго, я уверен, что большинство реализаций pthread используют реализацию futex для своих мьютексов.Это означает, что они довольно быстрые, когда нет конкуренции, и требуют вмешательства операционной системы только при наличии конкуренции.

0 голосов
/ 30 января 2011

Если вам действительно нужно только увеличить этот элемент (или аналогичную простую арифметику), вам просто нужны атомарные операции.

  • Большинство (все?) Современных процессоров поддерживают их с родными инструкциями.
  • Я не знаю о других компиляторах, но те из семьи GCC имеют они как встроенные.

К сожалению, похоже, что нет стандартизированного интерфейса с ними, но в следующем стандарте C (C1x) они будут.

0 голосов
/ 30 января 2011

Если вы не хотите использовать блокировки или критические секции, тогда самое простое решение - не сохранять состояние в самом объекте.Если вы измените свой класс следующим образом, он будет поточно-ориентированным:

// Class has no state, only operations on data. So it
// is thread-safe by nature.
class MyCls 
{
    int foo(int x = 0)
    {
        return ++x;
    }
};

// Usage
MyCls obj;
int x = obj.foo(); // x = 1
x = obj.foo(x); // x = 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...