Способы синхронизации
Для синхронизации я сейчас использую мьютексы, причём, фактически, делая из них критические секции. Не всегда это удобно, поэтому хотел бы спросить, а какие приёмы используете вы для синхронизации? (какие парадигмы, классы...?) Если есть возможность, то прямо код можно написать в пример. Буду рад также ссылкам, особенно на русском
Из мьютексов сделать критические секции - это сильно :) Какая задача у Вас? Универсальный способ синхронизации Вам вряд ли кто-то подскажет.
Семафоры - наше фсе. Для блокировки читателей-писателей - ReaderWriterLockSlim.
mutex mt;
......
mutex::scoped_lock scoped_lock(mt);
if (last==inMas) {
inMas++;
return false;
} else {
return true;
}
}
функция является критической секцией т.к. туда не зайдут 2 потока одновременно. Объект scoped_lock уничтожается по выходу из блока, снимая мьютекс.
Задачу сложно описать. Просто там много где требуется поставить какие-то элементы синхронизации.
задача - кэш.
Соответственно, упрощённо алгоритм выглядит так:
поискать страницу в кэше.
Если есть - вернуть её.
Если нет - вытолкнуть какую-то ненужную страницу, загрузить нужную и вернуть.
И проблема:
если 2 потока одновременно просят одну и ту же страницу и выполнение идёт так:
ищет 1ый - не находит. прерывание. Ищет второй - не находит. Выгружает какую-то страницу, загружает нужную - возвращает ссылку на неё. прерывание. Первый выгружает какую-то страницу, загружает нужную (хотя она уже есть в памяти в другом месте), возвращает ссылку на неё.
Даже уж не говоря о том, что если потоки планируют не только читать, но и писать в страницу, то это приведёт к несохранению каких-то данных, так и просто ну зачем в кэше хранить копии...
это .net :(
В принципе "мьютекс может всё", поэтому любую стратегию я реализию с их помощью, вероятно. но всё-таки есть загвоздка одна. Мне нужны какие-то способы, чтобы один из потоков стоял на месте и ждал, пока другой поток дойдёт до определённой строчки
+Sleep() определён в windows.h, что опять же не подходит...
Я не очень понимаю, почему нет комментариев к каждому методу буста. По названием неочевидно...по крайней мере мне
жжешь...
руки бы поотрывал
2sstorm
Вообще, я бы пока не заморачивался с кросс-платформенностью. Сделай абстрактный класс (назови, например, Synchronizer) и наследуй от него WinSynchronizer, в котором используй API. Когда (и если) дело дойдет до других ОС, то сделаешь прочие классы и все.
Посоветую учить английский.
Английский для программиста - это что ноты для музыканта, надо знать.
Вооружившись английским идем в Google ищем по ключу: multi-threading libraries
От себя отмечу boost:thread (http://www.boost.org/doc/libs/1_41_0/doc/html/thread.html)
и pthreads (http://ru.wikipedia.org/wiki/POSIX_Threads).
2sstorm
Вообще, я бы пока не заморачивался с кросс-платформенностью. Сделай абстрактный класс (назови, например, Synchronizer) и наследуй от него WinSynchronizer, в котором используй API. Когда (и если) дело дойдет до других ОС, то сделаешь прочие классы и все.
Да здесь глобальная - переменная пушистый кролик, по сравнению с циклом.
В том смысле, что нужно использовать события (семафоры и пр.), если можно?
А ещё лучше, пиши свои операционные системы. :D
Ты сам придумал такой дельный совет или прочитал в документации по операционным системам?
От себя отмечу boost:thread (http://www.boost.org/doc/libs/1_41_0/doc/html/thread.html)
и pthreads (http://ru.wikipedia.org/wiki/POSIX_Threads).
Вот в коде автодополнение указывает на то, что у mutex есть метод getEvent, к примеру. В этой документации, что по ссылке выше, нет ни слова об этом методе. А судя по названию, мне что-т подобное (со словм event) и нужно
static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mt); // вход в секцию
...
pthread_mutex_unlock(&mt); //выход из секции
return 0;
}
Если не хочется блокироваться на время ожидания освобождения мутекса:
static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
if ( pthread_mutex_trylock(&mt) == EBUSY ) { // другой поток уже в секции
return EBUSY;
} else { // входим в секцию
...
}
pthread_mutex_unlock();
return 0;
}
int main(void) {
while( CriticalFunction() == EBUSY ) {
DoSomeJobWhileWaiting();
}
// по выходу из цикла имеем выполнившуюся один раз функцию
}
Ты сам придумал такой дельный совет или прочитал в документации по операционным системам?
За исключением мьютексов все остальные методы синхронизации(семафоры, события, сообщения и т.д.) средства операционной операционной системы.
...неоперационной операционной системы...
А мютексы-то тогда что? Десница божья? :eek:
Средства операционной системы... не нужно использовать напрямую, кроме минимально необходимого. А вот знать очень полезно.
По вашей ссылке, GreenRiver, даже русские маны. Обидно, что я сразу её не выбрал. Теперь надо пересогласовывать будет и переписывать, если в ближайшие пару дней не смогу до"понять" буст
По вашей ссылке, GreenRiver, даже русские маны. Обидно, что я сразу её не выбрал. Теперь надо пересогласовывать будет и переписывать, если в ближайшие пару дней не смогу до"понять" буст
М-да... из пушки по воробьям...
Почему по воробьям? Если нужна кроссплатформенность, то Qt довольно хороший выбор (особенно если понадобится GUI). Или я что-то не так понял?
P.S. Похоже холивар все-таки получится ;)
[quote]Да здесь глобальная переменная - пушистый кролик, по сравнению с циклом.
В том смысле, что нужно использовать события (семафоры и пр.), если можно?
[/quote]
зы: если уж так хорошо все тут собрались, то можно попросить пояснить один момент из кутяшных доков:
Обратите внимание на то, что классы синхронизации Qt зависят от использования правильно выровненных (properly aligned) указателей. Например, вы не можете использовать упакованные классы вместе с MSVC.
В принципе я догадываюсь, что речь о выравнивании по границе 4 байт. Но даже если в этом я прав, возникают 2 вопроса:
1) в x64 граница тоже 4 байта?
2) Как определить какой класс является "упакованным", и почему нельзя использовать их в студии? А если юзать нетбинс, то становится возможным их использование?
Использовать Qt ради одной синхронизации - это и есть из пушки...
Qt - это в первую очередь UI framework.
Вы же не покупаете автомобиль ради пепельницы?
Ну sstorm тебе все уже доходчиво объяснил.
Добавлю только, что объекты синхронизации для того и существуют, чтоб их использовать для синхронизации, и не "когда можно", а всегда, когда есть необходимость в синхронизации.
Понял, спасибо.
1. буст всё равно довольно объёмен. Но больше мне в нём не нравится даже то, что помимо каких-то хедерсов он ещё потребовал lib'ы. Я что-то не так делал и этого можно было избежать? А если избежать нельзя, то это всё равно пушка, хоть и меньше размером.
2. Каким средством бы воспользовались вы? И если это буст, то каким образом нашли бы документацию к некоторым методам (скажем, mutex.getEvent()), если этого нет ни на boost.org, ни внутри исходников даже комментов