Что касается вашего второго вопроса, о том, как сделать блокировку: перевод потока в спящий режим и его пробуждение будет осуществляться ОС, это не ваше беспокойство. Но есть проблема с вашей схемой.
Вы хотите заблокировать доступ к ячейке, только если ее строка И столбец заблокированы. То есть разрешить доступ, если строка ИЛИ столбец разблокирована. Обычно это не так, как работают замки. Кроме того, если строка была заблокирована, но вы все равно разрешили доступ (поскольку столбец был разблокирован), вы все равно хотите заблокировать ее «больше». Это означает, что вам понадобится больше, чем мьютекс.
Лучшая реализация, которую я могу придумать, использует один атомарный счетчик для строк и условный переменный счетчик для столбцов. При доступе:
- Увеличить счетчик атомов в строке.
- Если предыдущее значение атомного счетчика было равно нулю, строка разблокировалась. Доступ в порядке.
- Увеличить переменную условия столбца. В идеале это не должно блокировать.
- Если счетчик строки был ненулевым, он был заблокирован. Может быть, блок на столбце.
- Подождите, пока переменная условия столбца не станет равной нулю. Установите его в единицу, прежде чем отпустить мьютекс.
- Когда вы закончите с доступом:
- Уменьшите условную переменную (не забудьте заблокировать ее) и дайте ей сигнал разбудить другие обращения, если она стала нулевой.
- Атомно уменьшить счетчик строк.
Это включает в себя небольшую сложную работу, но общее количество ресурсов блокировки в целом довольно мало. Кто-нибудь еще может сделать лучше (или найти контрпример к моей схеме)?
Также обратите внимание, что разбиение матрицы на строки и столбцы несколько произвольно. Если по этой схеме происходит слишком много конфликтов, вам, вероятно, следует разделить строки на половины (например).