Определить, когда объект не используется никакими другими потоками без блокировки? - PullRequest
0 голосов
/ 23 декабря 2009

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

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

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

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

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

Как я могу гарантировать, что нет потока, использующего старый экземпляр без операторов блокировки? (энергозависимые и блокированные предпочтительны)

Спасибо.

Ответы [ 4 ]

2 голосов
/ 23 декабря 2009

То, что вы пытаетесь реализовать здесь, очень похоже на подсчет ссылок (помните COM?). Вы, вероятно, можете сделать это с приращениями / уменьшениями - просто держите счетчик ссылок рядом с вашей ссылкой.

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

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

1 голос
/ 23 декабря 2009

Проблема заключается в том, что любой поток может взять ссылку на объект в стек, а затем делать с ним все, что он хочет. Нет способа предотвратить это для не поточных операций без использования общей блокировки.

Как правило, вы не должны пытаться работать с сборщиком мусора .NET - лучше выяснить, почему сборщики мусора занимают так много времени, и оптимизировать для этого (не создавайте так много экземпляров в первую очередь , может быть, операция O (n ^ 2), создающая много экземпляров?) вместо того, чтобы пытаться повторно использовать экземпляры потокобезопасным способом.

0 голосов
/ 23 декабря 2009

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

Теперь, если это действительно принесет вам какое-то представление, или если оно того стоит, я не могу сказать; -)

0 голосов
/ 23 декабря 2009

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

...