C++: Многопоточность и объект refcounted

Не с помощью CSS, нет. Префиксы поставщиков, такие как -moz- или -webkit-, используются для экспериментальных функций, которые еще не полностью стандартизированы. Они не предназначены для изменения поведения определенных браузеров; версий стандартных селекторов с префиксом производителя, таких как top, никогда не было.

Если вы видите различия в том, как ваш веб-сайт отображается в разных браузерах, вы, вероятно, сталкиваетесь с различиями в таблице стилей агента пользователя для этих браузеров. (Например, поскольку вы упоминаете панель поиска, поля или отступы для элемента ввода могут быть разными.) Используйте веб-инспектор в каждом браузере, чтобы определить, где возникает разница, затем примените свойства к соответствующим элементам, чтобы определить поведение согласован во всех браузерах, вместо того, чтобы пытаться исправить несоответствия после факта.

7
задан usac 16 March 2012 в 13:41
поделиться

7 ответов

Если количество является частью объекта затем, у Вас есть свойственная проблема, если один поток может пытаться увеличить подсчет ссылок, пока другой пытается удалить последнюю ссылку. Должно быть дополнительное значение на касательно счета для каждого глобально доступного указателя на объект, таким образом, можно всегда безопасно увеличиваться касательно количества, если у Вас есть указатель.

Одна опция состояла бы в том, чтобы использовать boost::shared_ptr (см. документы). Можно использовать бесплатные функции atomic_load, atomic_store, atomic_exchange и atomic_compare_exchange (которые заметно отсутствуют в документах) обеспечивать подходящую защиту при доступе к глобальным указателям на общие объекты. После того как Ваш поток имеет a shared_ptr при обращении к конкретному объекту можно использовать нормальные неатомарные функции для доступа к нему.

Другая опция состоит в том, чтобы использовать Joe Seigh, атомарного касательно - считаемый указатель из его atomic_ptr_plus проекта

4
ответ дан 7 December 2019 в 03:22
поделиться

размышление о Вашей проблеме немного..., что Вы говорите, состоит в том, что у Вас есть 1 объект (если refcount равняется 1), и все же 2 потока, оба вызова удаляют () на нем. Я думаю, что это - то, где Ваша проблема действительно заключается.

Наоборот эта проблема, если Вы хотите потоковый объект, который можно безопасно снова использовать между потоками, должна проверить, что refcount больше, чем 1 прежде, чем освободить внутреннюю память. В настоящее время Вы освобождаете его и затем проверяете, является ли refcount 0.

1
ответ дан 7 December 2019 в 03:22
поделиться

Конечно, каждый поток просто должен справиться с подсчетами ссылок правильно... Таким образом, если ThreadA и ThreadB оба работают с Obj1 затем И ThreadA и ThreadB должны владеть ссылкой на объект, и ОБА должны разъединение вызова, когда они сделаны с объектом.

В единственном потоковом приложении вероятно, что у Вас есть точка, где ссылка, считаемый объект создается, Вы затем, работает над объектом и в конечном счете разъединением вызова. В многопоточной программе Вы создали бы объект и затем передали бы его Вашим потокам (однако, Вы делаете это). Прежде, чем передать объект потоку необходимо назвать AddRef () на объекте дать потоку его собственный подсчет ссылок. Поток, который выделил объект, может затем назвать выпуск, поскольку он сделан с объектом. Потоки, которые работают с объектом, затем назовут выпуск, когда они будут сделаны и когда последняя ссылка будет выпущена, объект будет очищен.

Обратите внимание, что Вы не хотите код, который это работает на самих потоках для вызова AddRef () на объекте, поскольку у Вас затем есть состояние состязания между выпуском вызова потока создания на объекте перед потоками, которые Вы диспетчеризировали для получения шанса выполнить и назвать AddRef ().

3
ответ дан 7 December 2019 в 03:22
поделиться

Это не ответ, но просто немного совета. В такой ситуации, прежде чем Вы начнете фиксировать что-либо, удостоверьтесь, что можно надежно копировать эти проблемы. Иногда это - простое как выполнение Ваших модульных тестов в цикле некоторое время. Иногда помещение некоторых умных Снов в Вашу программу для принуждения условий состязания полезно.

Касательно подсчета проблем имеют тенденцию задерживаться, таким образом, инвестиции в Вашу тестовую обвязку окупятся в конечном счете.

1
ответ дан 7 December 2019 в 03:22
поделиться

Любой объект, который Вы совместно используете между потоками, должен быть защищен со взаимным исключением, и то же относится к дескрипторам refcount! Это означает, что Вы никогда не будете удалять последний дескриптор к объекту от двух потоков. Вы могли бы одновременно удалять два отличных дескриптора, которые, оказывается, указывают на один объект.

В Windows Вы могли использовать InterlockedDecrement. Это гарантирует, что точно один из двух декрементов возвратится 0. Только тот поток удалит объект refcounted.

Любой другой поток не мог копировать один из двух дескрипторов также. По общим правилам MT один поток не может удалить объект, все еще используемый другим потоком, и это расширяется на дескрипторы refcount также.

0
ответ дан 7 December 2019 в 03:22
поделиться

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

Библиотека Intel Thread Building Blocks (TBB) обеспечивает атомарные значения.

Кроме того, поэтому выполняет в библиотеке ACE ACE_Atomic_Op шаблон.

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

http://www.dre.vanderbilt.edu/Doxygen/Current/html/ace/a00029.html http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm

0
ответ дан 7 December 2019 в 03:22
поделиться

Я полагаю, что что-то вдоль этой строки решило бы Вашу проблему:

private:
    void Destroy()
    {
ACE_Guard< ACE_Mutex > guard( _refCountMutex ); // thread2 are waiting here if (_refCount != 0) { --(*_refCount); // This cause a free memory write by the thread2 if( 0 == *_refCount ) { delete _refCount; _refcount = 0; } } } private: mutable U32* _refCount; mutable ACE_Mutex _refCountMutex;
0
ответ дан 7 December 2019 в 03:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: