Название: QMutex Отправлено: niktagor от Сентябрь 22, 2010, 16:41 В документации написано:
QMutex::Recursive In this mode, a thread can lock the same mutex multiple times and the mutex won't be unlocked until a corresponding number of unlock() calls have been made. QMutex::NonRecursive In this mode, a thread may only lock a mutex once. Если у меня один QMutex на несколько потоков, в нерекурсивном режиме каждый поток сможет сделать ему свой lock()? Есть ли какие-нибудь гарантии, что они получят к нему доступ в том порядке, в котором они этот lock() вызвали? Название: Re: QMutex Отправлено: Авварон от Сентябрь 22, 2010, 17:22 мьютекс может быть заблокирован только один РАЗ (в случае рекурсивного лока, это не приведет к зависанию, если поток 1 и тот же локает несколько раз)
Название: Re: QMutex Отправлено: Igors от Сентябрь 22, 2010, 19:23 В документации написано: Абсолютно никаких, порядок не определен, это "базовая" установка/понятие. Вызвавший lock позже может захватить его (а не тот кто вызвал lock раньше).QMutex::Recursive In this mode, a thread can lock the same mutex multiple times and the mutex won't be unlocked until a corresponding number of unlock() calls have been made. QMutex::NonRecursive In this mode, a thread may only lock a mutex once. Если у меня один QMutex на несколько потоков, в нерекурсивном режиме каждый поток сможет сделать ему свой lock()? Есть ли какие-нибудь гарантии, что они получят к нему доступ в том порядке, в котором они этот lock() вызвали? Рекурсивный мутекc - в природе его нет, это просто удобная замена такого: Код
Название: Re: QMutex Отправлено: niktagor от Сентябрь 22, 2010, 19:24 мьютекс может быть заблокирован только один РАЗ (в случае рекурсивного лока, это не приведет к зависанию, если поток 1 и тот же локает несколько раз) А если разные потоки локают?Мне нужно, чтобы разные потоки могли читать/записывать в одну переменную. Причем каждый из них должен ждать освобождения переменной и ничего не делать в это время. Как лучше реализовать? Название: Re: QMutex Отправлено: Kolobok от Сентябрь 22, 2010, 19:32 А если разные потоки локают? Мне нужно, чтобы разные потоки могли читать/записывать в одну переменную. Причем каждый из них должен ждать освобождения переменной и ничего не делать в это время. Как лучше реализовать? Использовать QMutex. Он для этого и служит. Название: Re: QMutex Отправлено: Igors от Сентябрь 22, 2010, 19:35 А если разные потоки локают? Смотря что за переменная. Если напр. надо класть/извлекать из контейнера, то просто делать это под защитой мутексаМне нужно, чтобы разные потоки могли читать/записывать в одну переменную. Причем каждый из них должен ждать освобождения переменной и ничего не делать в это время. Как лучше реализовать? Код В более сложных случаях надо заботиться о том, что прочитанные данные уже изменены Название: Re: QMutex Отправлено: niktagor от Сентябрь 22, 2010, 20:11 В моей ситуации 10 процессов ждут доступа на чтение к одному очень большому массиву данных. А один процесс их довольно часто перезаписывает. И может возникнуть ситуация, когда пара процессов всегда будут тупо висеть в ожидании. Поэтому нужно реализовать очередность, чтобы первый вставший в очередь на считывание первым получил доступ. Как это лучше сделать?
Название: Re: QMutex Отправлено: Авварон от Сентябрь 22, 2010, 20:28 никак, это задача "удушения"
можно играться с приоритетом потоков, но в общем случае считается, что все потоки равноправны и кто получит доступ, неизвестно Название: Re: QMutex Отправлено: Igors от Сентябрь 22, 2010, 20:39 В моей ситуации 10 процессов ждут доступа на чтение к одному очень большому массиву данных. А один процесс их довольно часто перезаписывает. И может возникнуть ситуация, когда пара процессов всегда будут тупо висеть в ожидании. Поэтому нужно реализовать очередность, чтобы первый вставший в очередь на считывание первым получил доступ. Как это лучше сделать? Возможно с 10 читающими всего 1 пишущему трудно будет прорваться к записи, тогда надо использовать QReadWriteLock. По поводу того что, мол, какие-то нитки будут всегда стоять: распределением нагрузки занимается OC, так что "всегда" никто стоять не будет. Может быть что одна нитка выполнит 8 задач, а другая за это же время - всего 2. Это нормально, не надо стараться сделать 5/5 - скорость будет хуже. Название: Re: QMutex Отправлено: niktagor от Сентябрь 22, 2010, 20:43 Не может быть, чтобы не было решения. Пусть очередь будет сколь угодно большая. Нужна гарантия, что каждый поток будет продвигаться по ней только вперед, а не назад. Пусть не с помощью мутексов.
Первое, что пришло в голову: Создаем поток, занимающийся только обслуживанием очередности. У него для каждого потока есть свой отдельный мутекс. Когда он видит, что данные изменились, он разблокирует мутекс нужного потока и тот устремляется к данным. Будет работать. Но должно же быть красивое решение! Цитировать Возможно с 10 читающими всего 1 пишущему трудно будет прорваться к записи, тогда надо использовать QReadWriteLock Так и буду делать. Но нужно еще заботиться о том, чтобы все читающие иногда получали доступ. Пусть не после каждого изменения данных, но получали.Название: Re: QMutex Отправлено: Akon от Сентябрь 22, 2010, 20:45 2 niktagor:
QMutex mutex; mutex.lock(); mutex.lock(); // Error QMutex mutex(QMutex::Recursive); mutex.lock(); mutex.lock(); // OK Вся разница. Нерекурсивный мьютекс это частный случай рекурсивного. Название: Re: QMutex Отправлено: Igors от Сентябрь 22, 2010, 20:54 Но должно же быть красивое решение! :) Мне нравится Ваш подход, но решение "чего"? Как уже сказали "все нитки нагружены одинаково" = недостижимо. Тогда чего Вы хотите добиться? Пусть очередь будет сколь угодно большая. Нужна гарантия, что каждый поток будет продвигаться по ней только вперед, а не назад. Ну так это и будет само собой достигаться, зачем надо прилагать еще какие-то усилия?Название: Re: QMutex Отправлено: niktagor от Сентябрь 22, 2010, 21:04 Пусть очередь будет сколь угодно большая. Нужна гарантия, что каждый поток будет продвигаться по ней только вперед, а не назад. Ну так это и будет само собой достигаться, зачем надо прилагать еще какие-то усилия?Кажется, понял. Так и сделаю. Просто страшно пологаться в таком деле на Виндовс. Название: Re: QMutex Отправлено: Igors от Сентябрь 22, 2010, 21:30 QMutex mutex(QMutex::Recursive); Разница в том что второй лок просто ничего не лочит :)mutex.lock(); mutex.lock(); // OK Вся разница. Нерекурсивный мьютекс это частный случай рекурсивного. Название: Re: QMutex Отправлено: Akon от Сентябрь 23, 2010, 09:10 QMutex mutex(QMutex::Recursive); Разница в том что второй лок просто ничего не лочит :)mutex.lock(); mutex.lock(); // OK Вся разница. Нерекурсивный мьютекс это частный случай рекурсивного. Лочит - на каждый лок нужен анлок. Название: Re: QMutex Отправлено: Igors от Сентябрь 23, 2010, 09:58 Лочит - на каждый лок нужен анлок. Да, но второй и последующие lock/unlock просто сводятся к увеличению/уменьшению внутреннего счетчика QMutex, никаких вызовов ОС не происходит. Т.е. рекурсивный мутекс не является "чем-то особенным"Название: Re: QMutex Отправлено: Akon от Сентябрь 23, 2010, 10:31 Лочит - на каждый лок нужен анлок. Да, но второй и последующие lock/unlock просто сводятся к увеличению/уменьшению внутреннего счетчика QMutex, никаких вызовов ОС не происходит. Т.е. рекурсивный мутекс не является "чем-то особенным"Да не вопрос. Так и есть. |