поучительная история про мальчика билли

Aug 20, 2009 12:01

Три дня бился с зависанием, казалось бы, несложной двух-с-половиной-поточной программы.
(Один поток - UI, второй - рабочий, половинный - асинхронные колбеки непонятно откуда из MAPI).

Сперва сделал всё академически, на активных объектах, мониторах и условных переменных.
(про мониторы) )

программирование

Leave a comment

kodt_rsdn September 30 2009, 12:51:07 UTC
С мониторами идея в том, что если поток выходит за пределы монитора - как по return, так и по call, он должен снимать блокировку.
Примерно так:

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

Up