Три дня бился с зависанием, казалось бы, несложной двух-с-половиной-поточной программы.
(Один поток - UI, второй - рабочий, половинный - асинхронные колбеки непонятно откуда из MAPI).
Сперва сделал всё академически, на активных объектах,
мониторах и условных переменных.
(
(про мониторы) )
Примерно так:
void monitor1::foo()
{
lock lk(this->m_mutex);
.....
..... // здесь внутреннее состояние может быть каким угодно
.....
// к этому месту приводим объект в непротиворечивое состояние
{
unlock ulk(this->m_mutex);
mon2.bar();
}
// состояние непротиворечивое, но, возможно, изменившееся
.....
..... // продолжаем ковыряться в недрах
.....
}
Очень хорошо, если эта фича поддерживается на уровне языка. Вот надо бы взглянуть на Oberon - интересно, сделали они её или нет?
Собственно, ожидание условной переменной - частный случай такого временного покидания монитора.
А высокоуровневый дедлок завсегда можно получить, было бы желание :).
Поскольку на мониторах можно эмулировать семафоры, а на семафорах дедлок - как два пальца об асфальт.
На самом деле, для дедлока достаточно одного семафора (с рекурсивным захватом).
semaphore s;
void foo() { s.take(); s.give(); }
void bar() { s.take(); foo(); s.give(); }
s.init(2);
// один поток
s.take(); // 1
s.take(); // 0
s.give(); // 1
s.give(); // 2
// два потока
//thread1 //thread2
| |
s.take(); // 1 |
| s.take(); // 0
s.take(); // ждёт |
. s.take(); // ждёт
. .
. .
Reply
Leave a comment