 |
|

31.03.2012, 09:39
|
|
Новичок
Регистрация: 04.11.2004
Сообщений: 5
С нами:
11322426
Репутация:
0
|
|
Сообщение от C00LPack
а не проще & лучше вместо TThread юзать апи потоки? (beginthread - createthread)
Чем чистый апи может быть проще или лучше обертки?
|
|
|

31.03.2012, 14:19
|
|
Познающий
Регистрация: 31.08.2010
Сообщений: 30
С нами:
8262326
Репутация:
9
|
|
По мне гораздо легче использовать BeginThread/EndThreadEnterCrititcalSection/LeaveCriticalSection
Код:
procedure ProcedureForAllThreads();
begin
EnterCriticalSection(CS);
//Тут располагаем код, который должен выполняться только в одном потоке
LeaveCriticalSection(CS);
end;
thread:=BeginThread(nil,1024,@ProcedureForAllThreads,nil,0,ThreadIdVarCardinalType);
TerminateThread(thread,0);
|
|
|

31.03.2012, 14:25
|
|
Постоянный
Регистрация: 27.02.2011
Сообщений: 733
С нами:
8003126
Репутация:
19
|
|
Сообщение от ChymeNik
По мне гораздо легче использовать BeginThread/EndThread/EnterCrititcalSection/LeaveCriticalSection!
Зачем такие заморочки с этими тяжелыми обертками?
Чем они тяжелы тем что не заставляют каждый раз одно и тоже писать??
Ну и когда захотеться оптимизировать свою работы, создать класс для работы с потоками под. специфические задачи легче унаследоваца от TThread чем пелить велосипед и отлаживать его.
TThread это прежде всего абстракция над апи потоками дабы программист думал как реализовать функции которые будут в потоке а не как их запилить.
Ну и разработка с TThread быстрее осуществляются и по качеству апи потокам не уступает.
К томуже кучу классов готовых придумали дабы сэкономить наше время.
А где CloseHandle(thread)?
Уу все утечка хэндлов....
На мдсне не нашел строчек о том что TerminateThread хэндл закрывает..
Код:
procedure ProcedureForAllThreads();
begin
EnterCriticalSection(CS);
//Тут располагаем код, который должен выполняться только в одном потоке
LeaveCriticalSection(CS);
end;
А убивать через TerminateThread нужно только в крайних случаях, не советуйте плохого)
Лучше через ExitThread();
|
|
|

31.03.2012, 15:27
|
|
Познающий
Регистрация: 31.08.2010
Сообщений: 30
С нами:
8262326
Репутация:
9
|
|
А чего именно плохого в закрытии потока через TerminateThread?
Код показан только для примера
|
|
|

31.03.2012, 15:33
|
|
Постоянный
Регистрация: 27.02.2011
Сообщений: 733
С нами:
8003126
Репутация:
19
|
|
А чего именно плохого в закрытии потока через TerminateThread?
Сообщение от None
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. For example, TerminateThread can result in the following problems:
If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.
(c)mdsn
И чем вообще плохо на апи потоки юзать, нету исключений, проверять рез. выполнения каждой функции ка кто напряжено.
|
|
|

31.03.2012, 15:34
|
|
Новичок
Регистрация: 04.11.2004
Сообщений: 5
С нами:
11322426
Репутация:
0
|
|
Сообщение от mironich
Лучше через ExitThread();
"Поток можно завершить принудительно, вызвав ExitThread. При этом освобождаются все ресурсы операционной системы, выделенные дан ному потоку, но C/C++ - pеcypcы (например, объекты, созданные из С++-классов) не очищаются. Именно поэтому лучше возвращать управление из функции потока, чем самому вызывать функцию ExitThread." (Д. Рихтер)
|
|
|

31.03.2012, 15:38
|
|
Постоянный
Регистрация: 27.02.2011
Сообщений: 733
С нами:
8003126
Репутация:
19
|
|
Сообщение от M_script
"Поток можно завершить принудительно, вызвав ExitThread. При этом освобождаются все ресурсы операционной системы, выделенные дан ному потоку, но C/C++ - pеcypcы (например, объекты, созданные из С++-классов) не очищаются. Именно поэтому лучше возвращать управление из функции потока, чем самому вызывать функцию ExitThread." (Д. Рихтер)
Чет я не вкурил.
Но у меня обычно на BeginThread код так.
Код:
procedure;
begin
ExitThread(0);
end;
Сообщение от None
pеcypcы (например, объекты, созданные из С++-классов) не очищаются
В каком понятии очистить если я принудительно вызываю перед завершением потока деструкторы?
|
|
|

31.03.2012, 15:50
|
|
Новичок
Регистрация: 04.11.2004
Сообщений: 5
С нами:
11322426
Репутация:
0
|
|
Забыл совсем, что речь о делфи. Не пишу, поэтому не знаю, может там как-то по-другому.
|
|
|

31.03.2012, 17:09
|
|
Постоянный
Регистрация: 29.08.2010
Сообщений: 840
С нами:
8265206
Репутация:
84
|
|
Нового не нашел ничего, при чтении/изучении кода вероятность запутаться больше, нежели что-то понять, особенно для новичков. Был бы благодарен, за четкую, статейку с подробным описание и примерами по синхронизации потоков.
За старания +.
|
|
|

23.12.2019, 13:55
|
|
Новичок
Регистрация: 04.12.2018
Сообщений: 20
С нами:
3917846
Репутация:
0
|
|
работает , даже в memo записывает ,
.SpoilerTarget" type="button">Spoiler: 1
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
potok = class(TThread) //Этой строкой мы унаследовали класс потока
private
str: string;//в разделе private описываются переменные с помощью которых мы
nomer : Integer;//будем передавать значения между процедурами внутри потока
protected
procedure Execute; override;//это главная процедура потока, она начинает свою работу
//после того как мы создали поток
public
procedure synchro;//в разделе public вы можете объявить процедуры какие только душе
//угодно
constructor Create(CreateSuspended: Boolean);//эта строка говорит о том, что мы в
//implementation опишем конструкцию
//потока
end;
var
a: array [1..10] of potok;
Form1: TForm1;
nom:integer;
implementation
constructor potok.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);//Эта строка говорит о том, что поток после создания
//будет приостановлен если ему передать значение true при создание, если false, то сразу
//начнёт работу.
end;
{$R *.dfm}
procedure Ping(IP: String; OutMemo:TMemo);
const BUFSIZE = 2000;
var SecAttr : TSecurityAttributes;
hReadPipe,
hWritePipe : THandle;
StartupInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
Buffer : Pchar;
WaitReason,
BytesRead : DWord;
begin
with SecAttr do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
if Createpipe (hReadPipe, hWritePipe, @SecAttr, 0) then
begin
Buffer := AllocMem(BUFSIZE + 1);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.hStdOutput := hWritePipe;
StartupInfo.hStdInput := hReadPipe;
StartupInfo.dwFlags := STARTF_USESTDHANDLES +
STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_HIDE;
if CreateProcess(nil,
PChar('ping.exe '+IP),
@SecAttr,
@SecAttr,
true,
NORMAL_PRIORITY_CLASS,
nil,
nil,
StartupInfo,
ProcessInfo) then
begin
repeat
WaitReason := WaitForSingleObject( ProcessInfo.hProcess,100);
Application.ProcessMessages;
until (WaitReason <> WAIT_TIMEOUT);
Repeat
BytesRead := 0;
ReadFile(hReadPipe, Buffer[0], BUFSIZE, BytesRead, nil);
Buffer[BytesRead]:= #0;
OemToAnsi(Buffer,Buffer);
OutMemo.Text := OutMemo.text + String(Buffer);
until (BytesRead
|
|
|
|
 |
|
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|