Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.09.04;
Скачать: CL | DM;

Вниз

"Проверь себя". Тест для начинающих.   Найти похожие ветки 

 
Игорь Шевченко ©   (2005-08-09 13:42) [80]

pasha_golub ©   (09.08.05 13:36) [78]

Ответы Таненбаум не приводит :)


 
pasha_golub ©   (2005-08-09 13:45) [81]

Игорь Шевченко ©   (09.08.05 13:42) [80]
Ну, я, если честно, на Таненбаума и не надеялся. Я думал, ты расскажешь. :)


 
Игорь Шевченко ©   (2005-08-09 13:50) [82]

pasha_golub ©   (09.08.05 13:45) [81]

Ты полагаешь, я могу правильно ответить на все вопросы ? :) Ошибаешься :)


 
Piter ©   (2005-08-09 14:14) [83]

Игорь Шевченко ©   (09.08.05 13:17) [76]
"Вопросы по WinAPI" без понимания того, как работает система, считаю бесполезной тратой времени


вот Андрей в [77] хорошо написал. Что мне мешает водить машину, если я не знаю внутреннего устройства двигателя?

Оно, конечно, знать неплохо, но вовсе не обязательно. Как считаете?


 
Суслик ©   (2005-08-09 14:20) [84]


> Оно, конечно, знать неплохо, но вовсе не обязательно. Как
> считаете?


Совершенно не обязательно, но полезно, т.к. может (или нет) открыть новые перспективы.


 
Юрий Зотов ©   (2005-08-09 14:20) [85]

> Piter ©   (09.08.05 14:14) [83]

> Оно, конечно, знать неплохо, но вовсе не обязательно.

А никто и не заставляет. Просто будет уже не 50 баллов, а меньше. А 50 получат те, кто знает. Вот и будет видно, кто - водитель, кто - водила, а кто - ездила. В чем, собственно, цель теста и состоит.


 
Андрей Жук ©   (2005-08-09 14:24) [86]

Юр, а вы БД проектировали?
Если это опенсорсная разработка - то вы еще можете посмотреть исходники. И то, даже если это простенький Firebird, там исходников на 40 Мб.
А если это Oracle или MSSQL?
Сокрытие данных - оно не только в ОО программировании нужно.
Не пытайся объять необъятное.


 
jack128 ©   (2005-08-09 14:33) [87]

Суслик ©   (09.08.05 12:10) [74]
я думал ты сам, Игорь, их придумал :)))
я сходу только на 10ый могу ответить.


А на 9ый ??


 
Суслик ©   (2005-08-09 14:44) [88]


> [87] jack128 ©   (09.08.05 14:33)
> А на 9ый ??


Ну это надо смотреть, я так не помню:

1. закончился последний поток процесса
2. terminateprocess
3. exitprocess
4. необработанное исключение

вроде все, только почему-то уже 4. :))

но я смотрел, т.к. не помню exitprocess или processexit.

может еще что?


 
Piter ©   (2005-08-09 14:53) [89]

Суслик ©   (09.08.05 14:44) [88]
закончился последний поток процесса


хм. По-моему, если закончился ОСНОВНОЙ ПОТОК процесса

Суслик ©   (09.08.05 14:44) [88]
необработанное исключение


Это как? О каком исключении ты говоришь?


 
Суслик ©   (2005-08-09 14:57) [90]


>  [89] Piter ©   (09.08.05 14:53)


> хм. По-моему, если закончился ОСНОВНОЙ ПОТОК процесса

может и так, я уже подзабыл - как прочел с тех пор это знание не пригождалось.


> Это как? О каком исключении ты говоришь?

если в приложении (в одном из потоков) есть необработанное исключение, то приложение снимается системой. Это я в рихтере видел. Сейчас лень идти искать. Но там, где про потоки и контексты потоков говорится.


 
Piter ©   (2005-08-09 15:18) [91]

Суслик ©   (09.08.05 14:57) [90]
если в приложении (в одном из потоков) есть необработанное исключение, то приложение снимается системой


Да не... Ну как такое может быть? Может, поток там снимается?


 
Суслик ©   (2005-08-09 15:26) [92]


>  [91] Piter ©   (09.08.05 15:18)

да вроде все приложение.
На самом деле я не очень помню, т.к. при регулярной работе это не нужно, но если тебе в этом нужна помощь могу вечером почитать рихтера, поставить опыты и завтра рассказать.


 
Суслик ©   (2005-08-09 15:26) [93]

И вообще - сейчас прийдет кто-то знающий, навешает на нас значков и может прояснить ситуацию :)


 
jack128 ©   (2005-08-09 15:27) [94]

Суслик ©   (09.08.05 14:44) [88]
4. необработанное исключение


Исключения ВСЕГДА обрабатываются.. Если их не обработала программа, то исключение обработает система.  Стандартный обработчик -это всего лишь вызов ExitProcess, так что вот и получается, что вариантов всего три..
Суслик ©   (09.08.05 14:57) [90]
может и так, я уже подзабыл - как прочел с тех пор это знание не пригождалось.

нет, не так. Должны закончится ВСЕ потоки процесса.

Piter ©   (09.08.05 15:18) [91]
Да не... Ну как такое может быть? Может, поток там снимается?

Легко проверить

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils, Windows;

function ThreadProc(Param: Pointer): Integer;
begin
 Sleep(1000);
 raise Exception.Create("Test");
end;
var
 Dummy: THandle;
begin
 CloseHandle(BeginThread(nil, 0, ThreadProc, nil, 0, Dummy));
 ReadLn;
end.


 
Суслик ©   (2005-08-09 15:47) [95]


> [94] jack128 ©   (09.08.05 15:27)


> нет, не так. Должны закончится ВСЕ потоки процесса.

значит изначально прав был.

А по поводу необработанных исключений, думаю надо почитать, т.к. память мне говорит иное.


 
jack128 ©   (2005-08-09 15:59) [96]

Суслик ©   (09.08.05 15:47) [95]
> нет, не так. Должны закончится ВСЕ потоки процесса.

значит изначально прав был.

Кстати говоря, доказать не совсем просто, дело в том, что RTL при завершении основного потока принудительно вызывает ExitProcess, так что для док-ва нужен примерно такой код:

program Project1;
uses
 SysUtils, Windows;

function OpenThread(
 dwDesiredAccess: DWORD;
 bInheritHandle: BOOL;
 dwThreadId: DWORD
): THandle; stdcall; external "kernel32.dll" name "OpenThread";

const
 THREAD_TERMINATE  = $0001;

function ThreadProc(Param: Pointer): Integer;
var
 h: THandle;
begin
 h := OpenThread(THREAD_TERMINATE, False, MainThreadId);
 if h = 0 then
   raise Exception.Create("ХАНА");
 if not TerminateThread(h, 0) then
   RaiseLastWin32Error;
 Sleep(10000);
end;

var
 Dummy: THandle;
 h: THandle;
begin
 CloseHandle(BeginThread(nil, 0, ThreadProc, nil, 0, Dummy));
 Sleep(100); // ждем пока дополнительный поток начнет работу..
end.


 
Суслик ©   (2005-08-09 16:04) [97]


>  [96] jack128 ©   (09.08.05 15:59)

под win надо доказывать на vc++ 6. imho.

В дельфе главную функцию (ту, которая еще главнее main) фиг подменишь.


 
GuAV ©   (2005-08-09 16:27) [98]


jack128 ©   (09.08.05 15:27) [94]

> нет, не так. Должны закончится ВСЕ потоки процесса.


Всегда думал иначе, решил проверить.
Оказывается, приложение таки остаётся работать с другими потоками, однако IDE реагирует так, будто приложение полностью завершило работу. Странно.


 
GuAV ©   (2005-08-09 16:29) [99]

program thdtest;

uses
 Windows;

function SleepThd(Parameter: Pointer): Integer;
begin
 Sleep(DWORD(Parameter));
end;

var ID: DWORD;
begin
 CloseHandle(BeginThread(nil, 0, SleepThd, Pointer(4000), 0, ID));
 ExitThread(0);
end.


IDE включает дизайнеры сразу, однако приложение 4 сек болтается в процессахю


 
jack128 ©   (2005-08-09 18:11) [100]

GuAV ©   (09.08.05 16:29) [99]
IDE включает дизайнеры сразу, однако приложение 4 сек болтается в процессахю

Что значит "включает дизайнеры" ??   В семерке кнопка Run 4 секунды заблокированна, как и положенно.. А про exitthread я чего то не подумал..


 
jack128 ©   (2005-08-09 18:12) [101]

GuAV ©   (09.08.05 16:27) [98]
Всегда думал иначе, решил проверить.

А я тоже так всегда думал..   И очень многие так думают, потому что
jack128 ©   (09.08.05 15:59) [96]
RTL при завершении основного потока принудительно вызывает ExitProcess


 
GuAV ©   (2005-08-09 19:11) [102]

jack128 ©   (09.08.05 18:11) [100]
Что значит "включает дизайнеры" ??   В семерке кнопка Run 4 секунды заблокированна, как и положенно..


У меня нет, сразу нажимается повторно.
"дизайнеры" - Object TreeView, Object Inspector.

build 7.0.4.453


 
Eraser ©   (2005-08-09 19:38) [103]

Завершение процесса
Процесс можно завершить четырьмя способами:

входная функция первичного потока возвращает управление (рекомендуемый способ);
один из потоков процесса вызывает функцию ExitProcess (нежелательный способ);
поток другого процесса вызывает функцию TerminateProcess (тоже нежелательно);
все потоки процесса умирают по своей воле (большая редкость).
В этом разделе мы обсудим только что перечисленные способы завершения процесса, а также рассмотрим, что на самом деле происходит в момент его окончания.

(C) Джеффри РИХТЕР


 
GuAV ©   (2005-08-09 19:50) [104]


> входная функция первичного потока возвращает
> управление (рекомендуемый способ);


Вот только что разобрались, что этот способ сводится к

> один из потоков процесса вызывает функцию ExitProcess
> (нежелательный способ);


Что насчёт рекомендуемый/нежелательный, скорее всего имеется ввиду что при ExitProcess (в отличии, кстати, от Halt)не выполнятся финализации модулей (и код после ExitProcess, который тоже может содержать важный код заваершения).

Джеффри РИХТЕР писал про MS С++, а про на Delphi, но я не думаю что есть принципиальные для этой темы отличия.


 
Eraser ©   (2005-08-09 19:57) [105]

GuAV ©   (09.08.05 19:50) [104]
но я не думаю что есть принципиальные для этой темы отличия.


Согласен.


 
GuAV ©   (2005-08-09 20:10) [106]

Есть идея как точно проверить, вызывается ли ExitProcess кодом в ехе файле, выполняемым после end. Достаточно в своей таблице импорта перебить ExitProcess на ExitThread. Затем создать доп. поток, в нём задержку, или окно, а в основном дойти до end. . Если случай "входная функция первичного потока возвращает управление" - отдельный и [89] верно, то приложение должно завершится при end. , иначе - остаться работать до завершения доп. потока.


 
GuAV ©   (2005-08-09 20:18) [107]

Eraser ©   (09.08.05 19:38) [103]

Там же ниже, кстати, написано, что в первом (рекомендуемом) способе ExitProcess будет вызванна кодом рантайм библиотеки С/С++ (в нашем случае Delphi).


 
Eraser ©   (2005-08-09 20:25) [108]

GuAV ©   (09.08.05 20:18) [107]

Точно
Кстати, в документации из Platform SDK утверждается, что процесс не завершается до тех пор, пока не завершится выполнение всех его потоков. Это, конечно, верно, но тут есть одна тонкость. Стартовый код из библиотеки С/С++ обеспечивает завершение процесса, вызывая ExitProcess после того, как первичный поток Вашего приложения возвращается из входной функции. Однако, вызвав из нее функцию ExitThread (вместо того чтобы вызвать ExitProcess или просто вернуть управление), Вы завершите первичный поток, но не сам процесс — если в нем еще выполняется какой-то другой поток (или потоки).

соответсвенно 1 это просто следствие. RTL за-нас делает код правильным.


 
jack128 ©   (2005-08-09 21:48) [109]

GuAV ©   (09.08.05 20:10) [106]
Есть идея как точно проверить, вызывается ли ExitProcess кодом в ехе файле, выполняемым после end.

вообще говоря достаточно воспользоваться hot-key"ем из из твоей анкеты ;)


 
Игорь Шевченко ©   (2005-08-10 09:48) [110]

Eraser ©   (09.08.05 19:38) [103]


> входная функция первичного потока возвращает управление
> (рекомендуемый способ);


> все потоки процесса умирают по своей воле (большая редкость).
>


И чем это, собственно, отличается ?


 
Думкин ©   (2005-08-10 10:50) [111]


> [110] Игорь Шевченко ©   (10.08.05 09:48)
> Eraser ©   (09.08.05 19:38) [103]

Ну, типа в 10-ку. А чем?


 
GuAV ©   (2005-08-10 14:01) [112]

Игорь Шевченко ©   (10.08.05 9:48) [110]

> > входная функция первичного потока возвращает
>управление
>> (рекомендуемый способ);
>
>
> > все потоки процесса умирают по своей воле (большая
>редкость).
>>
>
>
> И чем это, собственно, отличается ?


Вызываемой функцией ExitProcess в первом / ExitThread во втором случае. Возможным наличием других "неявно завершенных" потоков в первом случае. Нет ?

Хотя, если бы не было вызова ExitProcess в коде RTL после end. , то, наверное ничем бы эти способы не отличались.


 
Игорь Шевченко ©   (2005-08-10 14:20) [113]


> Вызываемой функцией ExitProcess в первом / ExitThread во
> втором случае


Я полагаю, что завершение процесса происходит вне зависимости от наличия RTL :)


 
GuAV ©   (2005-08-10 17:02) [114]

Игорь Шевченко ©   (10.08.05 14:20) [113]

>Я полагаю, что завершение процесса происходит вне зависимости от наличия RTL :)

IMHO, неверно.

Отдельный тест на asm показал, что когда первичный поток возвращает управление, а другой поток ещё нет, работа другого потока не прекращается.

.386
locals
jumps
.model flat,STDCALL

extrn            CreateThread:PROC
extrn            ExitProcess:PROC
extrn            ExitThread:PROC
extrn            GetModuleHandleA:PROC
extrn            MessageBoxA:PROC

GetModuleHandle  equ <GetModuleHandleA>
MessageBox       equ <MessageBoxA>

.data

hInst              dd 0
ThdID              dd 0

szTitleName        db "Win32 Assembly Program", 0
szPrimaryThread    db "Click ok to exit primary thread",0
szSecThread        db "Click ok to exit secondary thread",0

;-----------------------------------------------------------------------------

.code

thread:

       push    0
       push    OFFSET szTitleName
       push    OFFSET szSecThread
       push    0
       call    MessageBox

       ; push    0
       ; call    ExitThread

       ret 4

start:

       push    0
       call    GetModuleHandle         ; get hmod (in eax)
       mov     [hInst], eax            

       push    OFFSET ThdID            ; pointer to returned thread identifier
       push    0                       ; creation flags
       push    0                       ; argument for new thread
       push    OFFSET thread           ; pointer to thread function
       push    0                       ; initial thread stack size, in bytes
       push    0                       ; pointer to thread security attributes  
       call    CreateThread

       push    0
       push    OFFSET szTitleName
       push    OFFSET szPrimaryThread
       push    0
       call    MessageBox
       
       ; push    0
       ; call    ExitProcess

       ret

ends
end start


Процесс будет завершен только тогда, когда будут закрыты оба messagebox.


 
Игорь Шевченко ©   (2005-08-10 17:12) [115]

GuAV ©   (10.08.05 17:02) [114]


> Отдельный тест на asm показал, что когда первичный поток
> возвращает управление, а другой поток ещё нет, работа другого
> потока не прекращается.


Так с этим никто не спорит вроде.

Пожтому и остаются три способа - возврат управления всеми потоками, вызов ExitProcess и вызов TerminateProcess.
Так вроде получается.


 
Суслик ©   (2005-08-10 17:58) [116]


>  [115] Игорь Шевченко ©   (10.08.05 17:12)
> GuAV ©   (10.08.05 17:02) [114]
>
> Пожтому и остаются три способа - возврат управления всеми
> потоками, вызов ExitProcess и вызов TerminateProcess.
> Так вроде получается.


я все-таки думаю, что предложенный мной 4й способ (необработанное исключение в одном из потоков), представляет также верный ответ.


 
Игорь Шевченко ©   (2005-08-10 18:13) [117]

Суслик ©   (10.08.05 17:58) [116]

Необработанное исключение в одном из потоков приводит к вызову системной функции UnhandledExceptionFilter, после чего вызывается функция ExitProcess.


 
Суслик ©   (2005-08-10 18:26) [118]


>  [117] Игорь Шевченко ©   (10.08.05 18:13)

А почему ты уверен, что в действительности ExitProcess не вызывает TerminateProcess или наоборот?


 
GuAV ©   (2005-08-10 18:34) [119]

Суслик ©   (10.08.05 17:58) [116]
RaiseException + F1:

...

Remarks

...

Raising an exception causes the exception dispatcher to go through the following search for an exception handler:

1. The system first attempts to notify the process"s debugger, if any.
2. If the process is not being debugged, or if the associated debugger does not handle the exception, the system attempts to locate a frame-based exception handler by searching the stack frames of the thread in which the exception occurred. The system searches the current stack frame first, then proceeds backward through preceding stack frames.
3. If no frame-based handler can be found, or no frame-based handler handles the exception, the system makes a second attempt to notify the process"s debugger.
4. If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.


Итого, процесс можно завершить тремя способами:

1. Завершение всех потоков
потоки м.б. завершены возвратом потоковой функции или вызовом ExitThread.

2. вызов ExitProcess
ExitProcess м.б. вызванна непосредственно, возвратом из кода программы (достижением end. в Delphi, возвратом из main/WinMain/etc в C ...), стандартной обработкой исключения.

3. вызов TerminateProcess


 
Игорь Шевченко ©   (2005-08-10 18:36) [120]

Суслик ©   (10.08.05 18:26) [118]

Вообще-то обе они оканчиваются на NtTerminateProcess...



Страницы: 1 2 3 4 вся ветка

Текущий архив: 2005.09.04;
Скачать: CL | DM;

Наверх




Память: 0.72 MB
Время: 0.047 c
8-1114086942
anat
2005-04-21 16:35
2005.09.04
OpenGL транформация


1-1124071417
Uin
2005-08-15 06:03
2005.09.04
GIF в Image


1-1123094473
Juice
2005-08-03 22:41
2005.09.04
Отсутствие множественного наследования


1-1123867834
Андрей Молчанов
2005-08-12 21:30
2005.09.04
TTreeView неправильная прорисовка границ


1-1123834976
Санек
2005-08-12 12:22
2005.09.04
Как сделать неактивной TabSheet