| View previous topic :: View next topic |
| Author |
Message |
Chris M. Thomasson Guest
|
Posted: Wed Oct 15, 2008 1:50 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
"David Schwartz" <davids@webmaster.com> wrote in message
news:77f542a6-f523-494c-8fbe-fd42bda37b00@h60g2000hsg.googlegroups.com...
On Oct 14, 3:19 am, "Skybuck Flying" <BloodySh...@hotmail.com> wrote:
| Quote: | In theory TThread.FTerminated boolean would not need to be protected from
synchronization, since it's only one field/boolean which would be
atomically
accessed/write/read.
Atomicity is not relevant. This isn't an atomicity issue.
However in practice I have seen this theory "fail".
What? You've seen a boolean read or write fail to be atomic?
|
For further context, Skybuck Flying is a known troll with severe social
problems; don't waste your time, just plonk it.
[...] |
|
| |
|
Back to top |
Skybuck Flying Guest
|
Posted: Wed Oct 15, 2008 4:30 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
Test exception in destroy and execute.. so far no problem it seems...
Maybe Sza was right after all... maybe it's a rare hardware optimization
which causes some bugs ;)
Bye,
Skybuck. |
|
| |
|
Back to top |
Skybuck Flying Guest
|
Posted: Wed Oct 15, 2008 7:17 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
Maybe this "termination" problem is related to another problem:
"How to tell if a program will or will not terminate" ;)
I once read it's impossible to tell if a program will or will not terminate
;)
In this case the question is a little bit different:
The question is:
"Did the thread terminate yes or no".
That shouldn't be so hard ? ;)
Bye,
Skybuck. |
|
| |
|
Back to top |
Skybuck Flying Guest
|
Posted: Wed Oct 15, 2008 7:19 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
However maybe that's not really the question.
The real question is:
"What mechanism will garantuee termination ?"
That might indeed be much harder to figure out/prove ;)
Maybe even impossible ?! ;)
Bye,
Skybuck. |
|
| |
|
Back to top |
Skybuck Flying Guest
|
Posted: Wed Oct 15, 2008 7:37 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
Another possibility is I was using resume/suspend...
Now I have learned other techniques like Tevent etc...
I have read resume/suspend is buggy and is dangerous and Microsoft says it's
only to be used by debuggers not general programs ;)
Bye,
Skybuck. |
|
| |
|
Back to top |
Nicholas Ring Guest
|
Posted: Thu Oct 16, 2008 2:12 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
Skybuck Flying wrote:
| Quote: | I have read resume/suspend is buggy and is dangerous and
|
I haven't had any problem with it...
| Quote: | Microsoft says it's only to be used by debuggers not general programs
|
I have never read this. Have you got some reference (URL?) about this?
Cheers,
Nick |
|
| |
|
Back to top |
Chris M. Thomasson Guest
|
Posted: Thu Oct 16, 2008 7:55 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
"Skybuck Flying" <BloodyShame@hotmail.com> wrote in message
news:d4b38$48f47239$541981e1$32079@cache3.tilbu1.nb.home.nl...
| Quote: | Hello,
In theory TThread.FTerminated boolean would not need to be protected from
synchronization, since it's only one field/boolean which would be
atomically accessed/write/read.
However in practice I have seen this theory "fail".
[...] |
I do NOT program in Delphi at all, I have programmed Pascal many years
ago... Anyway, I downloaded a compiler and created the following trivial
program as a little test:
________________________________________________________________________
program thread_shutdown;
{$APPTYPE CONSOLE}
uses sysutils, windows;
const RUN_WAIT : integer = 250;
const SHUTDOWN_WAIT : integer = 1000;
const RUNS : integer = 5;
const THREAD_COUNT : integer = 64;
var g_io_mutex : TRTLCriticalSection;
var g_run : boolean;
procedure writeln_locked(buf : string);
begin
EnterCriticalSection(g_io_mutex);
writeln(buf);
LeaveCriticalSection(g_io_mutex);
end;
function thread_entry(state : Pointer) : Windows.DWORD; stdcall;
var tid_str : string;
begin
tid_str := 'tid(' + inttostr(GetCurrentThreadId()) + ')';
writeln_locked(tid_str + ' started');
while (g_run) do
begin
writeln_locked(tid_str + ' running...');
Sleep(RUN_WAIT);
end;
writeln_locked(tid_str + ' stopped');
Result := 0;
end;
var
r : integer;
i : integer;
tid : DWORD;
th : array of THandle;
begin
system.IsMultiThread := true;
setlength(th, THREAD_COUNT);
InitializeCriticalSection(g_io_mutex);
for r := 0 to RUNS - 1 do
begin
g_run := true;
writeln('---------------------------------------------');
writeln('TEST ' + inttostr(r + 1) + ' RUNNING...');
for i := 0 to THREAD_COUNT - 1 do
begin
th[i] := CreateThread(nil, 0, @thread_entry, nil, 0, tid);
end;
writeln_locked('threads created!');
Sleep(SHUTDOWN_WAIT);
g_run := false;
writeln_locked('terminate issued; waiting for termination...');
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
end;
writeln('threads shutdown!');
writeln('TEST ' + inttostr(r + 1) + ' COMPLETED!');
writeln('---------------------------------------------');
writeln;
writeln;
end;
DeleteCriticalSection(g_io_mutex);
writeln;
writeln;
writeln;
writeln('__________________________________________________');
writeln('hit <ENTER> to exit');
readln;
end.
________________________________________________________________________
AFAICT, it works for me. No hangs. It simple creates `THREAD_COUNT' of
threads, and sets a global variable to false to shut them down, then it
waits for them. And repeats `RUNS' of times.
Any thoughts? |
|
| |
|
Back to top |
Chris M. Thomasson Guest
|
Posted: Thu Oct 16, 2008 8:24 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
Well, I post the same program twice in last post here:
http://groups.google.com/group/comp.programming.threads/msg/e0e3b150446dcb3f
I posted the version using events twice. I don't want to post whole program
using boolean again, so alls you need to do is add a call to
`CloseHandle(th[i])' to the following program:
http://groups.google.com/group/comp.programming.threads/msg/5a41111724f5fcb7
You place this call right after the call to `WaitForSingleObject(th[i],
INFINITE)'; e.g.:
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
end;
should be:
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
CloseHandle(th[i]);
end;
Sorry for any confusions!
;^(... |
|
| |
|
Back to top |
Chris M. Thomasson Guest
|
Posted: Thu Oct 16, 2008 8:24 am Post subject: Re: TThread, Terminate, Boolean, Alignment ??? |
|
|
"Chris M. Thomasson" <no@spam.invalid> wrote in message
news:WXxJk.2719$1r2.438@newsfe01.iad...
| Quote: | "Skybuck Flying" <BloodyShame@hotmail.com> wrote in message
news:d4b38$48f47239$541981e1$32079@cache3.tilbu1.nb.home.nl...
Hello,
In theory TThread.FTerminated boolean would not need to be protected from
synchronization, since it's only one field/boolean which would be
atomically accessed/write/read.
However in practice I have seen this theory "fail".
[...]
I do NOT program in Delphi at all, I have programmed Pascal many years
ago... Anyway, I downloaded a compiler and created the following trivial
program as a little test:
|
OOOPS!! I forget to call `CloseHandle(...)' on thread handles!!! OUCH!
| Quote: | ________________________________________________________________________
[...]
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
|
// should call CloseHandle!
| Quote: | end;
[...]
________________________________________________________________________
[...] |
Here is fixed program:
________________________________________________________________________
program thread_shutdown;
{$APPTYPE CONSOLE}
uses sysutils, windows;
const RUN_WAIT : integer = 0;
const SHUTDOWN_WAIT : integer = 1;
const RUNS : integer = 10;
const THREAD_COUNT : integer = 32;
var g_io_mutex : TRTLCriticalSection;
var g_run : THandle;
procedure writeln_locked(buf : string);
begin
EnterCriticalSection(g_io_mutex);
writeln(buf);
LeaveCriticalSection(g_io_mutex);
end;
function thread_entry(state : Pointer) : Windows.DWORD; stdcall;
var tid_str : string;
begin
tid_str := 'tid(' + inttostr(GetCurrentThreadId()) + ')';
writeln_locked(tid_str + ' started');
while (WaitForSingleObject(g_run, 0) = WAIT_TIMEOUT) do
begin
writeln_locked(tid_str + ' running...');
Sleep(RUN_WAIT);
end;
writeln_locked(tid_str + ' stopped');
Result := 0;
end;
var
r : integer;
i : integer;
tid : DWORD;
th : array of THandle;
begin
system.IsMultiThread := true;
setlength(th, THREAD_COUNT);
InitializeCriticalSection(g_io_mutex);
g_run := CreateEvent(nil, TRUE, FALSE, nil);
for r := 0 to RUNS - 1 do
begin
writeln('---------------------------------------------');
writeln('TEST ' + inttostr(r + 1) + ' RUNNING...');
for i := 0 to THREAD_COUNT - 1 do
begin
th[i] := CreateThread(nil, 0, @thread_entry, nil, 0, tid);
end;
writeln_locked('threads created!');
Sleep(SHUTDOWN_WAIT);
SetEvent(g_run);
writeln_locked('terminate issued; waiting for termination...');
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
CloseHandle(th[i]);
end;
ResetEvent(g_run);
writeln('threads shutdown!');
writeln('TEST ' + inttostr(r + 1) + ' COMPLETED!');
writeln('---------------------------------------------');
writeln;
writeln;
end;
CloseHandle(g_run);
DeleteCriticalSection(g_io_mutex);
writeln;
writeln;
writeln;
writeln('__________________________________________________');
writeln('hit <ENTER> to exit');
readln;
end.
________________________________________________________________________
Here is version of program which does not use a shutdown flag; its uses
event instead:
________________________________________________________________________
program thread_shutdown;
{$APPTYPE CONSOLE}
uses sysutils, windows;
const RUN_WAIT : integer = 0;
const SHUTDOWN_WAIT : integer = 1;
const RUNS : integer = 10;
const THREAD_COUNT : integer = 32;
var g_io_mutex : TRTLCriticalSection;
var g_run : THandle;
procedure writeln_locked(buf : string);
begin
EnterCriticalSection(g_io_mutex);
writeln(buf);
LeaveCriticalSection(g_io_mutex);
end;
function thread_entry(state : Pointer) : Windows.DWORD; stdcall;
var tid_str : string;
begin
tid_str := 'tid(' + inttostr(GetCurrentThreadId()) + ')';
writeln_locked(tid_str + ' started');
while (WaitForSingleObject(g_run, 0) = WAIT_TIMEOUT) do
begin
writeln_locked(tid_str + ' running...');
Sleep(RUN_WAIT);
end;
writeln_locked(tid_str + ' stopped');
Result := 0;
end;
var
r : integer;
i : integer;
tid : DWORD;
th : array of THandle;
begin
system.IsMultiThread := true;
setlength(th, THREAD_COUNT);
InitializeCriticalSection(g_io_mutex);
g_run := CreateEvent(nil, TRUE, FALSE, nil);
for r := 0 to RUNS - 1 do
begin
writeln('---------------------------------------------');
writeln('TEST ' + inttostr(r + 1) + ' RUNNING...');
for i := 0 to THREAD_COUNT - 1 do
begin
th[i] := CreateThread(nil, 0, @thread_entry, nil, 0, tid);
end;
writeln_locked('threads created!');
Sleep(SHUTDOWN_WAIT);
SetEvent(g_run);
writeln_locked('terminate issued; waiting for termination...');
for i := 0 to THREAD_COUNT - 1 do
begin
WaitForSingleObject(th[i], INFINITE);
CloseHandle(th[i]);
end;
ResetEvent(g_run);
writeln('threads shutdown!');
writeln('TEST ' + inttostr(r + 1) + ' COMPLETED!');
writeln('---------------------------------------------');
writeln;
writeln;
end;
CloseHandle(g_run);
DeleteCriticalSection(g_io_mutex);
writeln;
writeln;
writeln;
writeln('__________________________________________________');
writeln('hit <ENTER> to exit');
readln;
end.
________________________________________________________________________
BTW, I forgot how much I liked Pascal back when I actually used it!
;^D |
|
| |
|
Back to top |
|