On Fri, 03 Jun 2005 16:34:53 +0400, adontz <2053@users.rsdn.ru> wrote:
> Решение судя по всему кросс-компиляторное.
> Что кинуть исключение в другом потоке (и вообще как метод одноразовой передачи сообщения потоку)
[]
> Мне такое удобно делать, чтоб остановить поток слушающий сокет, потому что message-queue там нету и по-другому сообщение не передать.
Куря кольян, на меня снизошло понимание: брошенное таким способом исключение разрушает любой код, включая код с гарантиями strong exception safety и nothrow. Этот метод нельзя использовать никогда, когда предполагается восстановление и продолжение работы после обработки исключения.
Код с гарантиями strong exception safety и nothrow и весь код на С полагается на операции, которые гарантировано не бросают исключений, такие, как, например, многие простые операции над встроенными типами.
Рассмотрим операцию вставки в двусвязанный список. Эта операция является nothrow (конечно при условии, что указатели валидны).
static node* prepend(node* head, node* n)
{
n->prev = head->prev;
n->next = head;
head->prev->next = n; // (*)
return head->prev = n;
}
Для валидного списка, этот код всегда исполняется от начала до конца, т.к. операции присвоения для валидных указателей никогда не могут бросить исключения.
Если в поток, выполняющий этот код, пробросить исключение предлагаемым варварским методом в тот момент, когда была выполнена строка (*), но не была еще выполнена следующая строка, список будет разрушен. Чтобы этот код сохранил свойство nothrow при таких новых условиях, когда исключение может возникнуть в любой момент из ниоткуда "на ровном месте", возможно необходимо либо
каждую строку обернуть в __try / __except конструкцию, либо, возможно, исполнять весь код в блоке __finally (я не спец в SEH). Никто, естественно, в здравом уме этого делать не будет. Примеры подобного кода можно приводить бесконечно.
Вывод из этого следующий: ты просто не можешь прервать выполнение любого потока в произвольной точке и перевести управление при помощи исключения в другую точку, ожидая при этом, что состояние структур данных сохранит инвариант и останется в каком-либо относительно корректном состоянии.
Да, поначалу выглядит круто порулить руками регистрами и наебать остальной код и компилятор, но if you lie to the compiler, it will take its revenge...
--
Maxim YegorushkinPosted via RSDN NNTP Server 1.9