есть ли способы синхронизации потоков менее требовательные к ресурсам чем использование mutex или criticalsection ? пока пытаюсь использовать interlocked функции но реализовать с их помощью то что мне нужно сложно. может есть для этого готовые библиотеки ?
События именованые не подходят? Счего ты взял что те же мъютексы требовательны к ресурсам? Например в српавочнике по недокументированым АПИ Гарри Неббета есть статистика вызываемости апи, так вот ф-и событий, мутантов и т.д. вызываются чаще других в несколько раз. По 400к за несколько часов работы!
просто в моем случае существует много потоков которые часто используют глобальные данные для чтения (несколько больших списков std::list) и один поток который их модифицирует (значительно реже чем происходит чтение). я проверял - если убрать синхронизацию ping у клиентов уменьшается (в два раза когда клиентов много) но при этом сервер через некоторое время естественно падает. (уточнение: сервер WoWEmu, клиент WorldOfWarcraft)
Я конечно не знаю что это за программы, но могу сказать что при программированиии сетей при большом кол-ве подключений многопоточное сетевое приложение не покатит. Нужно использовать порты завершения. Сам посчитай на тот же 1 поток система выделит 1 метр (если стек не укажешь вручную)
kropalik 1] потоки сами по себе нехилый тормоз, особенно при большом их числе, использование "самопальных" механизмов "корпоративной" многозадачности иногда ускоряет производительность в десятки раз; 2] мутанты - тормоз по жизни, поскольку реализованы в ядре, а ядро это переключение контекста и т.д. критические секции реализованы в NTDDL.DLL и довольно эффективны. радикально оптимизировать их уже не удастся...
"... один поток который их модифицирует (значительно реже чем происходит чтение)... " В стандарте POSIX специально для такого случая предусмотрена блокировка чтения/записи - posix_rwlock_t - но это под никсы (к тому же она является необязательной, и её я, пока, не встречал). При большом желании можно реализовать подобную под Win: несколько переменных, мьютекс и два сообщения. У Стивенса описано. Если много читающих и один пишущий - может получиться даже быстрее, чем с одним мьютексом - за счет того, что при чтении запись блокируется на очень короткое время.
>> Нужно использовать порты завершения знаю. но WoWEmu писал не я, а переделывать сейчас все - новых багов будет больше чем исправленных старых. >> потоки сами по себе нехилый тормоз, особенно при большом их числе там их фиксированное количество (устанавливается в .conf файле) >> блокировка чтения/записи - posix_rwlock_t я и хотел найти нечто подобное под win32 >> У Стивенса описано. можно подробнее ?
После описания rwlock Стивенс приводит пример, как можно реализовать такой объект с помощью мьютексов и условных переменных (если я не ошибаюсь, то же что и события). опишу содержимое структуры mutex lock; //для защиты структуры event Readers; //для ждущих читающих потоков event Writers; //для ждущих пишущих потоков int nreaders; //количество читающих int nwriters; //количество пишущих int refcount; //(-1) - если ресурс заблокирован на запись, иначе количество блокировок на чтение при блокировании на запись: Если ресурс заблокирован (refcount != 0), то увеличиваем nwriters и ждем разрешения заблокировать на запись (Writers) Выставляем refcount в (-1) - блокируем на запись при блокировании на чтение: (приоритет в пользу пишущего потока) Если ресурс заблокирован на запись или ожидает блокирования на запись (refcount<0 || nwriters>0),то увеличиваем nreaders и ждем разрешения на чтение (Readers) Когда ресурс будет свободен от записи - увеличиваем refcount - блокируем на чтение при разблокировке: изменяем refcount проверяем есть ли запрос на запись (nwriters>0) и, при свободном ресурсе, разрешаем запись (Writers) иначе если есть запрос на чтение разрешаем всем чтение (Readers)
хм... надеюсь идея понятна. P.S. В рамках POSIX - rwlock очень просто реализовать, а вот как в Win32... При входе в процедуру, lock нужно захватить при выходе соответственно - отпустить. Но ещё lock нужно отпускать при ожидании сообщения - в POSIX оба действия делаются вместе и атомарно - условные переменные хорошо продуманы. А как в Win... и можно ли разнести эти действия по времени... ломает уже думать...
>> надеюсь идея понятна. да вполне. только непонятно насколько это будет лучше чем CriticalSection. я надеялся найти что нибудь типа библиотеки rwlock без вызовов api. все равно все сводится к выполнению инструкций с префиксом LOCK например InterlockedIncrment это всего лишь lock xadd [ecx], eax в общем если не найду - придется самому писать, только не вполне понятно как отлаживать...
имеется в виду что функции типа WaitForSingleObject в любом случае выполняют часть кода в ring0 в отличие от например InterlockedIncrement.
Да.... пробовал и так и сяк - в итоге напился до чёртиков. Как запустить обработку 11 задач на машине с 8 кб оперативки?