![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
SABROG |
|
||||||||||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
В Qt каждый созданный QObject добавляет в конструкторе мутекс на адрес экземпляра класса в общий пул мутексов. Я нигде не нашел, чтобы мутекс удалялся, даже когда память под объект уже давно освобождена. Пул мутексов мочится целиком только когда последний QObject в программе уничтожен. Заинтересовала эта строчка формирования индекса:
Если предположить, что объекты размеров в байт будут располагаться по адресам 100,101,102:
То на все эти адреса будет один и тот же мутекс? Теперь увеличим дистанцию на 32 бита, возможно мутексы не умеют работать с данными меньше 4х байт:
Тут каждый объект получил по своему личному мутексу. А теперь увеличим размер указателя до 8 байт (вообще указатель void* может иметь разные размеры на одной и той же машине?):
То есть на 2 объекта по 1 общему мутексу. Я чего-то не понимаю или залочка одного мутекса для одного объекта может блокировать работу другого объекта? Что если объекты находятся вообще в разных потоках и работают асинхронно? Ну и соответственно если я создам пару миллионов объектов, то из-за операции взятия остатка на многие из них будут снова общие мутексы. Означает ли это, что каждый раз, когда я в слоте пытаюсь узнать кто послал сигнал через метод sender():
То вот этот "друг"
Может заблокировать параллельно еще какой-нибудь случайный QObject, например QTcpSocket, который пытается принять в отдельном потоке клиента? Потому, что:
Может получить общий мутекс? Или у меня с математикой что-то плохо? |
||||||||||||||||
|
|||||||||||||||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
а точно signalSlotMutexes является QMutexPool * ?
может быть не является вызовом -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Он так объявлен в qobject.cpp:
То есть это своего рода "умный указатель" QBasicAtomicPointer. |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
SABROG, да, уже посмотрел. получается, что действительно вызов sender() может заблокировать вызов sender() из другого объекта. заметь, блокируется не объект, а вызов sender(), и не более того
P.S. Может стоит перенести тему в "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" ? Это сообщение отредактировал(а) borisbn - 28.3.2010, 23:03 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
sender() я взял как наиболее часто употребимый вариант, но там и другие методы есть, которые вызывают блокировку.
Речь не совсем о Qt, меня интересует верность рассчетов индекса от адреса объекта. Задача скорее математическая. Либо я чего-то не правильно посчитал, либо это так и есть. Может быть просто кто-то видел подобный алгоритм поиска объекта в массиве по адресу объекта в других проектах? Это сообщение отредактировал(а) SABROG - 28.3.2010, 23:34 |
|||
|
||||
borisbn |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
по-моему, это обычный hash (кстати, в более ранней версии Qt использовался как раз QHash, а не остаток от деления) ну, а если быть совсем точным, то
верно для 64-х битных указателей, т.к. для 32-х разрядной ОС sizeof(address) >> 1 = 2, т.е. должно быть
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||
|
|||||||
SABROG |
|
||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Обрати внимание, там сдвиг идет в 2 этапа:
4 >> 1 эквивалентно: 4/2 = 2 Потом второй этап:
То есть смещение уже зависит от размера указателя. А смещение на 2 эквивалентно делению на 4. Вот таблица, чтобы понятней было:
Отсчет ведется с 1 до 10. Первая цифра смещение на 1 == делению на 2, смещение на 2 == делению на 4 и так далее. В QHash не обнаружил подобного кода. --- Сейчас погуглил, наткнулся на такой код:
То есть правда в твоих словах есть. Остается понять откуда взялась вторая часть и почему хеш получается не уникальным. --- При беглом прочтении нескольких статей про хэши сделал вывод, что коллизия обычное дело. Если она возникает, то обычно сравниваются уже значения, если они разные, то происходит rehash. В случае с Qt слежения за коллизиями я не увидел, так как сами адреса нигде не хранятся, вместо них хранятся данные, которые никак к адресам не привязаны. Воозможно еще проблема в том, что я взал маленькие значения адресов, может быть при каких-нибудь 0x00410000h я буду уже не так часто получать коллизии? Это сообщение отредактировал(а) SABROG - 29.3.2010, 00:42 |
||||||||
|
|||||||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
SABROG,
1. Про сдвиг значения указателя на 2 -я протупил 2. В старом, ещё trolltech'вском коде mutex получался через QHash от указателя 3. Значение самого указателя (100 или 410000h) не играет роли, т.к. они берут остаток от деления на количество mutex'ов. Слежения за коллизиями я тоже не увидел, значит получается, что все функции, использующие QMutexPool могут блокировать друг друга -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Написал троллям, посмотрим чего они скажут.
|
|||
|
||||
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Thiago Maciera написал такой ответ и пометил багрепорт как invalid:
Говорит, что размер объекта почти никогда не бывает 1 байт и обычно составляет несколько размеров указателя void*. Раз несколько, то минимум 8 байт (по 4 байта на указатель). Но я оставил коммент, что даже в этом случае коллизии есть. ---
Хотят компилируемый пример с тормозами ![]() --- Кому интересно, за перепиской с троллями можно наблюдать тут. Выяснилась еще одна особенность. Максимальное количество мутексов - 131. Если при этом в программе 10 тысяч объектов, то на каждый мутекс может приходится 70-80 объектов. При 200 объектах это значение не так великов 1-5, но факт остается фактом, а возможность коллизии довольно большая. P.S.: математический вопрос считаю решенным, тема перетекла в русло Qt, можно переместить в соответствующий раздел. Спасибо borisbn за подсказку с хэшами, плюс один. Это сообщение отредактировал(а) SABROG - 29.3.2010, 21:55 |
||||
|
|||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
хитрые тролли ![]() ---------------------------------------- Vladislav, прочитал переписку. IMHO - очень дельное предложение сделать отдельный QMutexPool для каждого потока. Буду следить за войной русского программиста с финскими кодерами ![]() Это сообщение отредактировал(а) borisbn - 30.3.2010, 10:18 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |