Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];
ВнизВозбуждение исключения в другом потоке Найти похожие ветки
← →
vertal © (2005-01-10 23:51) [0]Пусть есть свой работающий поток (его hThread и ThreadID). Вопрос: знает ли кто-нибудь, можно ли из другого потока возбудить в первом исключение? В этом же потоке - просто raise Exception.Create("Случилось нечто ужасное"), а в другом?
← →
Piter © (2005-01-11 00:12) [1]Как ты вообще себе это представляешь? какой смысл возбуждать исключение в ДРУГОМ кодовом потоке? Ты ведь даже понятия не имеешь что делает ТОТ поток, как ты можешь вызывать исключение там?
Если тебе это требуется в твоем приложении - то у тебя неправильная логика приложения.
Например, чтобы грамотно остановить поток - нужно сделать ему Terminated, а сам поток должен проверять соответствующее свое свойство...
← →
Fay © (2005-01-11 02:16) [2]Можно из доп. потока ждать Event, а дождавшись - ругаться.
← →
Поручик © (2005-01-11 02:58) [3]
> Если тебе это требуется в твоем приложении - то у тебя
> неправильная логика приложения.
Если ты не можешь ответить - то у тебя неправильная логика мышления
Удачи
← →
KSergey © (2005-01-11 07:35) [4]> [3] Поручик © (11.01.05 02:58)
> Если ты не можешь ответить - то у тебя неправильная логика
> мышления
Так может блеснете правильной логикой?
← →
Kerk © (2005-01-11 07:40) [5]да запросто.. берешь @ThreadProc.. забиваешь начиная с этого адреса все нулями.. будет тебе исключение.. :) только надо поставить разрешение на запись в сегмент кода
← →
Fay © (2005-01-11 09:27) [6]>> забиваешь начиная с этого адреса все нулями
Всё - это сколько? 10 или 15?
8)
← →
Kerk © (2005-01-11 09:28) [7]Fay © (11.01.05 9:27) [6]
ну.. это надо посчитать.. надежней все разместить после ThreadProc какую-нибудь процедуру.. и вычислять размер @SomeProc-@ThreadProc
:) эх.. брутальные мысли в голову лезут
← →
Piter © (2005-01-11 09:45) [8]KSergey © (11.01.05 7:35) [4]
Так может блеснете правильной логикой?
может автор расскажет что ему нужно?
И как я понимаю, сам то ты считаешь это правильной логикой? Может, тогда приведешь пример реализации, а?
Я то свое мнение выразил - ты не имеешь понятия что конкретно делает сейчас другой кодовый поток, поэтому нету никакого смысла возбуждать там исключение.
Исключение - это так сказать ответ на какие-то определенные неправильные действия - деление на ноль, неудачный вызов конструктора объекта.
А как ДРУГОЙ поток может узнать делит ли на ноль сейчас этот поток или нет? Что он может знать, чтобы возбудить исключение?
Я свое мнение обосновываю, теперь прошу обосновать ваше мнение
Поручик © (11.01.05 2:58) [3]
Если ты не можешь ответить - то у тебя неправильная логика мышления
а, вот оно что. Одна проблема - я то как раз ответил, а вот ты - нет
Удачи
всегда удивляла эта приписка. К месту и не к месту.
Это типа "ну и пошел ты на #$%" ?
Желаю здоровья.
← →
vertal © (2005-01-11 21:15) [9][1],[4] и другие
Я могу ответить, но не могу сидеть в сети круглые сутки.
Предположим, что в этом потоке все сидит в блоке
try
делать чего-то
except
освободить ресурсы
end;
Есть три варианта его завершения - штатное, путем проверки флага в каком-то внутреннем цикле и просто по TerminateThread. Сейчас для досрочного выхода используется проверка флага. TerminateThread не гарантирует освобождения ряда ресурсов, и вообще, мне необходимо выполнение кода, следующего за except, в случае прерывания работы потока. Если бы можно было возбудить в том потоке исключение, то можно было бы избавиться от проверки флага. Исключение будет возбуждаться при сигнале пользователя о том, что он хочет прервать процедуру, этот сигнал ловится в другом потоке, и при этом неважно, что делает поток, который необходимо прикрыть (в крайнем случае можно поставить критическую секцию). Такой подход не кажется мне очень кривым. По сравнению с проверкой флага, здесь на мой взгляд два преимущества:
1) Не нужно дожидаться, когда на этот флаг обратят внимание
2) Не нужно вообще помнить про этот флаг.
← →
Piter © (2005-01-12 01:16) [10]vertal © (11.01.05 21:15) [9]
Предположим, что в этом потоке все сидит в блоке
try
делать чего-то
except
освободить ресурсы
end;
а я всегда думал, что правильно так:try
делать чего-то
finally
освободить ресурсы
end;
vertal © (11.01.05 21:15) [9]
просто по TerminateThread
Просто? не веришь мне - поверь документации MS:
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination
эту функцию можно выполнять только в КРАЙНИХ СЛУЧАЯХ, когда других путей просто нет, также как и TerminateProcess
vertal © (11.01.05 21:15) [9]
Сейчас для досрочного выхода используется проверка флага
и это правильная логика
TerminateThread не гарантирует освобождения ряда ресурсов
правильно, потому что это критическая функция, на самый крайний случай, она вообще не должна ничего гарантировать
Если бы можно было возбудить в том потоке исключение, то можно было бы избавиться от проверки флага
а можно гланды удалять через ж#&у
Не нужно дожидаться, когда на этот флаг обратят внимание
проверяй флаг почаще - вот и все
Не нужно вообще помнить про этот флаг
этот флаг специально ввели для упрощения КОРРЕКТНОГО ЗАВЕРШЕНИЯ ПОТОКА.
Хочешь делать правильно - делай. Хочешь изобретать велосипед - изобретай. Только сразу прими во внимание, что твой велосипед скорее всего будет не такой велосипедистый, как уже придуманный велосипед
← →
KSergey © (2005-01-12 08:13) [11]> [9] vertal © (11.01.05 21:15)
Тут уже была такая ветка.
Еще раз, кратко: никакой поток, никакая ф-ция не может быть корректно прервана извне. А потому от флага и его проверки никуды не уйти.
> [8] Piter © (11.01.05 09:45)
А по поводу чего взелся-то? Я ж вроде не к тебе... :-)
← →
Digitman © (2005-01-12 08:52) [12]
> vertal
неверна сама формулировка вопроса, ибо исключение может возбудить только сам трэд и никто кроме него
но заставить "чужой" трэд выполнить фрагмент кода, безусловно ведущий к искл.ситуации, можно и теоретически и практически.
для этого следует приостановить выполнение трэда (suspend), изменить его контекст так чтобы новый его eip указывал на участок кода, выполнение которого заведомо приведет к искл.ситуации, и после этого возобновить выполнение трэда (resume)
← →
Piter © (2005-01-12 16:47) [13]KSergey © (12.01.05 8:13) [11]
А по поводу чего взелся-то? Я ж вроде не к тебе
сори, не так прочитал
← →
vertal © (2005-01-12 17:58) [14]Спасибо авторам [2], [11] и [12] - эти посты несут содержательную информацию.
А по поводу блока
try
finally
end;
и
try
except
end;
то вторым тоже можно пользоваться для освобождения ресурсов:
try
p := Nil;
GetMem(p,SomeSize);
...
здесь может появиться исключение
...
FreeMem(p);
p := Nil;
except
if p <> nil then FreeMem(p);
end;
Это может не самый удачный пример, но возможен такой расклад , что часть ресурсов нужно освобождать всегда, а часть - только при досрочном завершении потока, и тогда как раз except на мой взгляд удобен. А при штатном завершении та часть ресурсов, которая не была освобождена, будет использоваться в вызывающем потоке как результат вычислений.
Говоря "просто по TerminateThread" я имел в виду только то, что ее просто вызвать в любой момент и обычно она отрабатывает.
А насчет замечания о велосипедах - я хочу сделать красиво и не считаю это стремление равносильным изобретению велосипеда.
← →
Piter © (2005-01-13 15:14) [15]vertal © (12.01.05 17:58) [14]
try
p := Nil;
GetMem(p,SomeSize);
...
здесь может появиться исключение
...
FreeMem(p);
p := Nil;
except
if p <> nil then FreeMem(p);
end;
А чем отличается от такого:try
GetMem(p, SomeSize);
...
здесь может появиться исключение
...
finally
FreeMem(p)
end;
vertal © (12.01.05 17:58) [14]
но возможен такой расклад , что часть ресурсов нужно освобождать всегда, а часть - только при досрочном завершении потока
примеры?
← →
Piter © (2005-01-13 15:15) [16]vertal © (12.01.05 17:58) [14]
я хочу сделать красиво
как сделать красиво тебе уже сказали.
← →
KSergey © (2005-01-13 15:38) [17]> [15] Piter © (13.01.05 15:14)
> try
> GetMem(p, SomeSize);
> ...
> здесь может появиться исключение
> ...
> finally
> FreeMem(p)
> end;
Только не так!!!
Тогда уж:
GetMem(p, SomeSize);
try
...
здесь может появиться исключение
...
finally
FreeMem(p)
end;
← →
Piter © (2005-01-13 16:49) [18]KSergey © (13.01.05 15:38) [17]
Ну да, да. Торопился просто...
← →
Erik1 © (2005-01-13 17:05) [19]to vertal
Да дела, если действительно хочеш красиво и правильно. То придется тебе всю твою логику переделывать. Посмотри примеры от Borland погляди исходники в инете может проникнешся. Еще стоит обратить внимание на семейство функций WaitFor... WaitForMultiObject. Вобщем работы много, когда появатся настоящие вопросы, спрашивай.
← →
vertal © (2005-01-13 21:17) [20]> [15] Примеры?
Пусть в результате работы этого потока формируется какая-нибудь структура данных, причем если он перывается досрочно, то эта структура заполняется не полностью и потом не используется, а если штатно, то используется и после этого освобождается. Не вижу причин, мешающих ее освобождению по этому условию в том блоке try..except.
> [19]
Что переделывать? Здесь как раз все наперебой говорят, что проверка флага и является единственно правильным решением, она сейчас и используется. И при чем здесь Wait-функции? Для организации ожидания сигнала пользователя о том, что он хочет прервать процесс? Их я тоже сейчас использую. Только прямого отношения к вопросу они не имеют.
← →
Piter © (2005-01-13 23:27) [21]vertal © (13.01.05 21:17) [20]
Пусть в результате работы этого потока формируется какая-нибудь структура данных, причем если он перывается досрочно, то эта структура заполняется не полностью и потом не используется, а если штатно, то используется и после этого освобождается
ок, эта структура после заполнения используется в другом потоке как я понимаю? В чем проблема?
Поток заполняет структуру. Если заполнение успешно - то он сообщает об этом другому потоку или сообщает о том, что операция не выполнена. Сообщает он об этом любым видом межпроцессорной/межпотоковой связи. Это будет правильно логикой.
← →
vertal © (2005-01-14 22:02) [22]> [21] ... Это будет правильной логикой.
Пусть так. Может быть пример с try..except с самого начала был не совсем удачным, но дело не в этом.
Короче, как я понял:
1) Поток все-таки лучше завершать через проверку флага
2) Возбудить в нем исключение все-таки можно, но не штатными средствами языка Delphi, а через SuspendThread и модификации внутренних структур Windows, отвечающих за его регистры.
Что касается логики - я не настаиваю, что задумка является красивым решением. Она могла бы оказаться таким, если бы в Delphi или Windows существовал механизм, стандартное решение для этого. Я потому и спросил, чтобы узнать, есть такой механизм или нет, и использует ли кто-нибудь такой вариант.
Предлагаю прекратить обсуждение, тем более что постов непосредственно по теме немного.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.045 c