Для примера рассмотримли подсчет ссылок поточно
class ProcessList {
private
std::vector<std::shared_ptr<SomeObject>> list;
Mutex mutex;
public:
void Add(std::shared_ptr<SomeObject> o) {
Locker locker(&mutex); // Start of critical section. Locker release so will the mutex - In house stuff
list.push_back(std::make_shared<SomeObject>(o).
}
void Remove(std::shared_ptr<SomeObject> o) {
Locker locker(&mutex); // Start of critical section. Locker release so will the mutex - In house stuff
// Code to remove said object but indirectly modifying the reference count in copy below
}
void Process() {
std::vector<std::shared_ptr<SomeObject>> copy;
{
Locker locker(&mutes);
copy = std::vector<std::shared_ptr<SomeObject>>(
list.begin(), list.end()
)
}
for (auto it = copy.begin(), it != copy.end(); ++it) {
it->Procss(); // This may take time/add/remove to the list
}
}
};
Одна нитка Process
. Несколько потоков запускают добавление/удаление.
Будет ли отсчет ссылок безопасным и всегда правильным - или должен ли быть помещен мьютекс вокруг него?
Подсчет ссылок может быть реализован поточно-безопасно. Учитывая, что у вас есть C++ 11, который также имеет потоки, я бы предположил, что refcounting также реализуется поточно-безопасным способом. BTW: Даже оригинальный 'shared_ptr' из Boost был уже потокобезопасным. –
Имеет ли каждый счетчик ссылок мьютекс? –
Нет, они используют атомные операции. Вы могли бы реализовать их, используя мьютекс для каждого счетчика, но это было бы неэффективно. Вы также можете реализовать их, используя один глобальный мьютекс, который будет проще, но, вероятно, еще менее эффективен, чем использование атомистики. –