Rectangle 27 0

gabr probably mentioned main new additions. What was left probably is the new overloads for TThread.Synchronize and TThread.Queue which can now execute anonymous methods.

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe
Rectangle 27 0

UPDATE: I'm not saying the way I got past the problem is a good solution. I need to take Rob Kennedy's notes and do some refactoring. However, to get past the problem for now I gave the thread it's own Window and WndProc() and at the top of the thread Execute loop I have a PeekMessage() while loop with calls to TranslateMessage() and DispatchMessage(). I no longer have a problem with setting breakpoints in the thread, but obviously this compounding of WndProc() methods indicates a structural problem in my code. I wanted to add this reply to fill out the discussion. I'm hoping that once I put Rob's suggestions to work when I clean up my WndProc() methods on the relevant forms, especially the main form, I can get rid of the this new WndProc() that I just added to the thread.

multithreading - Delphi 6 : breakpoint triggered on non-VCL thread sto...

multithreading delphi vcl repaint wndproc
Rectangle 27 0

Can you check if the timer is really owned by the new thread (TProcess) or by the main one? Timers in windows are "owned" (in terms of the resource manager) by threads, not processes. If your timer is owned by the main thread then the OnTimer event will be running in the context of the main thread, and even if you explicitly call Execute, the call will still be in the context of the main thread, no matter if Execute is a "procedure of object" which happens to be a TThread descendant.

And you may not explicitly call Execute anyway. This procedure is called (in the context of the new thread) when the thread runs.

Better try this: Inside Execute, create the timer using the windows api functions, and wait infinitely (SleepEx) with the alertable parameter set to TRUE. Then the timer will indeed be firing in the context of the new thread. Alternatively in the OnTimer event (in the context of the main thread) you can be posting APC procedure calls to the worker thread (you will still need to wait in SleepEx and set alertable to TRUE). A completely different alternative: in the OnTimer event create the thread object and do the normal processing inside Execute - FreeOnTerminate should be set to true so that the object is freed after finishing.

And one final note, I'm not sure if you can pass that EnumProcess function (a function declared inside a "procedure of object" ???) to a WinApi call. This may well be causing the crashes. I think you need a function declared at global level.

Regarding the final note, it's bad practice in my view, but in the 32 bit compiler it works fine so long as you don't refer to any variables in the enclosing scopes.

multithreading - Delphi - timer inside thread generates AV - Stack Ove...

multithreading delphi delphi-xe
Rectangle 27 0

I believe all of newly introduced features were covered already.

For the documentation part, here is an archived copy on classic tutorial book Martin Harvey. Multithreading - The Delphi Way. After reading you will most likely realize what there is no real need for any contributed libraries (except, maybe, the thread pool), remember, frameworks are not simplifying things for you, they also depriving you from the fine-grain control.

@TOndrej, a sequel! :-) Thanks!

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe
Rectangle 27 0

Also, in addition to what's already been mentioned:

TExternalThread
TThread.CurrentThread
  • while debugging in the IDE, you can now freeze and thaw individual threads.
  • a lot of new stuff in SyncObjs unit: support for condition variables, TLightweightEvent, TLightweightSemaphore, TSpinLock, TSpinWait, TInterlocked and more...

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe
Rectangle 27 0

This needs to be set up around the code segment which reads the next URL. To do this you would typically place a semaphore at the start of the code so that only one thread can enter it at any time. The semaphore is reset at the end of the code. As each new thread sees the URL list has expired, then it terminates.

Typically semaphores are boolean, but they can be integers for example if you want to allow a specific number of threads to enter the region at any time.

At the start of the region, the thread checks the flag. If it is false it sets it to true and enters the region (to get the next URL). If it is true, then it loops - e.g. repeat sleep(0) until (not fSemaphore). When it exits the region it set fSemaphore := False;

Obviously you need to make sure you guard against a possible infinite loop scenario...

multithreading - Delphi threads and variables - Stack Overflow

multithreading delphi delphi-7
Rectangle 27 0

As I told you in alt.comp.lang.borland-delphi earlier today, the problem is that Indy runs its event handlers in the same thread that does the blocking socket calls, which is not the same thread as your GUI. All GUI operations must take place in the same thread, but you are creating a new window in the socket thread.

To solve it, your event handler should post a notification to the main thread, which the main thread will handle asynchronously whenever it happens to next check for messages.

If you have a recent-enough Delphi version, you could try the TThread.Queue method, which works a lot like Synchronize, except the calling thread doesn't block waiting for the main thread to run the given method. They both have the same limitation regarding their method parameters, though; they only accept a zero-parameter method. That makes it cumbersome to transfer extra information for the method to use when it's eventually called. It's particularly bad for queued methods since whatever extra data you provide for them must remain intact for as long as it takes for the main thread to run it; the calling thread needs to make sure it doesn't overwrite the extra data before the queued method gets called.

A better plan is probably to just post a message to some designated window of the main thread. Application.MainForm is a tempting target, but Delphi forms are liable to be re-created without notice, so whatever window handle your other threads use might not be valid at the time they try to post a message. And reading the MainForm.Handle property on demand isn't safe, either, since if the form has no handle at the time, it will get created in the socket thread's context, which will cause all sorts of problems later. Instead, have the main thread create a new dedicated window for receiving thread messages with AllocateHWnd.

Once you have a target for messages to go to, you can arrange for threads to post and receive them. Define a message value and post them with PostMessage.

const
  am_NewQuery = wm_App + 1;

PostMessage(TargetHandle, am_NewQuery, ...);

To send the extra data the recipient will need to fully handle the event, messages have two parameters. If you only need two pieces of information, then you can pass your data directly in those parameters. If the messages need more information, though, then you'll need to define a record to hold it all. It could look something like this:

type
  PNewQuery = ^TNewQuery;
  TNewQuery = record
    Host: string;
    FromNickname: string;
  end;

Prepare and post the message like this:

procedure NewQuery(const Server, MsgFrom: string);
var
  Data: PNewQuery;
begin
  New(Data);
  Data.Host := Server;
  Data.FromNickname := MsgFrom;
  PostMessage(TargetHandle, am_NewQuery, 0, LParam(Data));
end;

Note that the caller allocates a new record pointer, but it does not free it. It will get freed by the recipient.

class procedure TSomeObject.HandleThreadMessage(var Message: TMessage);
var
  NewQueryData: PNewQuery;
begin
  case Message.Msg of
    am_NewQuery: begin
      NewQueryData := PNewQuery(Message.LParam);
      try
        Child := TFrmMessage.Create(NewQueryData.Host, NewQueryData.FromNickname);
        TN := GetNodeByText(ChanServTree, NewQueryData.Host, True); // Find parent node
        with ChanServTree.Items.AddChild(TN, NewQueryData.FromNickname) do begin
          Selected := True;
          Tag := 2; // TYPE OF QUERY
          Data := Child; // reference to form we created
        end;
      finally
        Dispose(NewQueryData);
      end;
    end;
    else
      Message.Result := DefWindowProc(TargetHandle, Message.Msg, Message.WParam, Message.LParam);
  end;
end;

I've made a couple of other changes to your code. One is that I made the child form's constructor accept the two pieces of information it needs to create itself properly. If the form wants its caption to be the nickname, then just tell it the nickname and let the form do whatever it needs to with that information.

According to what I'm reading, AllocateHWnd is not thread safe. Check this out: 17slon.com/blogs/gabr/2007/06/ still looking at that link and trying to reconcile both the fact that I'm in uncharted territory (personally) and your code with the code on that page.

Wow I'm lost. I'll sleep on this one and come back.

You're right. AllocateHWnd is not thread-safe. So only call it from the main thread when your program starts up, before you've created all the other threads. The function is not thread-safe, but the window handle it returns can be used from whatever threads you want. The handle is associated with the thread that created it.

So to use AllocateHWnd do I just create a new Type of Form (under type) then call it from say... my main form's oncreate?

multithreading - (Delphi 2009) idIRC, MDI, and problems with hanging -...

multithreading delphi delphi-2009 irc
Rectangle 27 0

Remy explained the problems... I've wanted to do this in Indy for a while so I posted a possible solution that I just put together to a new Google Code project instead of having a long comment here. It's a first-stab sort of thing, let me know if you have some changes to integrate: https://code.google.com/p/delphi-vault/

This code has two ways to Ping...multi-threaded clients as in your example, or with a simple callback procedure. Written for Indy10 and later versions of Delphi.

Your code would end up using a TThreadedPing descendant defining a SynchronizedResponse method:

TMyPingThread = class(TThreadedPing)
  protected
    procedure SynchronizedResponse(const ReplyStatus:TReplyStatus); override;
  end;
procedure TfrmThreadedPingSample.butStartPingClick(Sender: TObject);
begin
  TMyPingThread.Create('www.google.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.shouldnotresolvetoanythingatall.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.microsoft.com');
  TMyPingThread.Create('127.0.0.1');
end;

The threaded response is called in a synchronized method:

procedure TMyPingThread.SynchronizedResponse(const ReplyStatus:TReplyStatus);
begin
  frmThreadedPingSample.Memo1.Lines.Add(TPingClient.FormatStandardResponse(ReplyStatus));
end;

Wouah, you dit a lot of work. Great answer. Right now I'm modifying my code to use your implementation. Perhaps 2 comments. Fist one is to add/modify to be have somewhere a boolean answer of the pingReply. As in my case I just want to know yes/no is the computer connected. Another thing is that your code can interest many people and right now it is specific to my needs : defReceiveTimeout = 200; and defIPVersion = Id_IPv4; the user should be able to change these value to match his specific need (did you try ipv6 ? is it working).

+1, nice hit to make a shared place for StackOverflow projects! That brings me an idea to make my personal one and always share the whole project since I usually (almost always) test the stuff I'm posting, so now I'll just commit the full project to that personal storage and include also a link to the full project to the answer.

@Darian I have read your code carefully. Can you confirm me that I understood it correctly. The main idea in your code is to send multiple ping thread but get all the reply in the same procedure (InternalHandelReply), using SequenceId to know which is which. That way of doing (also as Remy said) also to treat every reply without discarding any of them and therefore treating them all ? Am I correct ? ...

... because in fact the result is not that much different than my "no thread code". In my case the ping response when not connected is about 3 seconds. What I was expecting was to have ALL the replies after 3 seconds. In the current code I have to wait for each computer for 3 sec, 60 PC = 3 minutes which is too long .. I am, looking for a way of getting the 40 replies at once and parse through them. The idea of @Remy of have 60 thread all replying to the same single replythread is what I am trying to do, so I can parse the replies manually with the sequenceID (do you understand what i mean)

Note that I corrected the data. I have 40 computers and 20 oscilloscopes (windows CE based) that's 60 devices not 40 as I first said.

multithreading - Delphi (XE2) Indy (10) Multithread Ping - Stack Overf...

multithreading delphi ping indy tthread
Rectangle 27 0

The internals of the Synchronize() mechanism have not changed much between D7 and D2009. Sure, there have been new features added (asynchronous queuing, anonymous methods, etc), but the core implementation to run code in the main thread has not changed. What is more likely happening is something else in your main thread code that you have not shown yet is blocking the main thread from processing pending messages and Synchronize() requests correctly.

Does my edit help answer the question? We've been digging into where the CheckSynchronize function is called and it's only when wm_null is passed to the active form, somehow there's a disconnect between passing it to the application and the form that is running the thread. This is what seems to have changed, probably something with the way MDI child forms are owned and notified by the MDI window, but I have no idea where to start looking for that in the VCL (or how to rectify it).

CheckSynchronize() is also called when TThread.WaitFor() is called in the context of the main thread, and whenever the main thread message loop goes idle after processing all of the pending messages in the queue.

Hey, I think you may have answered this already a few years ago, sorry for dredging it up. But, is this the same problem? (for the record, they're sharing the RTL bpl)

multithreading - TThread.Synchronize causing (near) deadlock in Delphi...

multithreading delphi delphi-7 delphi-2009
Rectangle 27 0

1 You need a version of Indy newer than 9.0.0.18, I think. Older ones have show-stopping threading bugs. That includes all versions of Indy delivered with Delphi up to version 7.

+1 For the server components at last. Some of the server components act freaky on earlier versions than 18 if they run on a multicore or HT system. (and that includes single core P4's with their HT)

multithreading - 100% CPU usage in Delphi - Stack Overflow

multithreading delphi udp
Rectangle 27 0

I've decided to send messages using a critical section with event signaling to tell the working threads that they have a message to process. Unfortunately, this means that the main thread have to check that the working thread processes any message before sending a new one.

Not necessarily. Give each thread a FIFO queue, protected by a critical section, and add an event to wait on. Signal the event when the FIFO is not empty.

I thought about that, but then if the main thread puts to many massages in the queue, the working thread will be forced to process them, and the working thread does some critical tasks in his loop. So if the working thread is processing any message, the main thread just dump the new messages instead of sending them to the working thread.

Sad really, a thread message queue would have been ideal. I'm still wondering why it doesn't work for you. I checked my implementation of this and you don't seem to be doing anything wrong from what you are saying. :(

multithreading - postthreadmessage and peekmessage problem in delphi 2...

delphi multithreading windows-xp message-queue peekmessage
Rectangle 27 0

This has mostly been answered in the comments and the bug report, but... The problem you are seeing is caused by a multithreading issue in XE's marshaller code. If two threads (or two clients) call a server server method which takes in or return user defined types (any type which will use the marshaller/unmarshaller) at the same time, then an exception could happen.

I am unaware of a perfect workaround for XE, but if it is possible to not use user-defined types, then you shouldn't see multithreading issues.

Hi Mat. Sure I can see that it only happens when using a user defined type. But that is one of the great forces of DataSnap as I see it. So basically its FAIL until they get it fixed? Looking at the structure of the program - I could rewrite the thread to use callback. So I would stop polling the server. But that really is just semantics. And would it help - I dont know.

In XE the marshaller code was not thread safe, which I agree was an unfortunate bug. Any solution which avoids using the marshaller (including callbacks) should avoid the issue.

"was not thread safe" ... sounds like you know a bit more - wanna share? :-)

I've tried several different things now. But going into callbacks is a bit tricky and faulty in XE - as long as we are using a tobject descendent. I've modified the channelcallback demo from embarcadero svn. And with the modified version it is possible to pass a tobject descendent in a callback. But not without going through the process of marshalling. QC#92921 is still "open" - and if it will be closed - I dont know.

multithreading - DELPHI: Multithreaded client/server datasnap error - ...

multithreading delphi datasnap
Rectangle 27 0

I think the "native" issues you are talking about are not related to the way TThread is implemented, but to other aspects of the RTL:

  • The memory manager is very fast and well written, but it fails to scale in a linear way when running with a number of concurrent threads on multiple cores;
  • Reference-counted types (like string and dynamic arrays) are implemented with an asm lock opcode to have atomic reference counting (InterlockedDecrement/InterlockedIncrement in x64), which may also scale badly on multi-threaded applications (that is, all cores freezes when this opcode is executed - even if newer CPUs made progress about this, an RCU implementation may scale better).

Those weakness are common to all multi-thread libraries - even OTL will suffer about this. They do exist since very early Delphi versions, and are still there with Delphi XE2. The 64 bit implementation is similar (even slower), and the Mac OS platform shares the very same implementation.

Please see this other SO question about how to write scaling multi-threaded applications in Delphi.

To be honest, both points above will appear only on some very specific kind of applications.

So there is nothing to worry about multi-threading in Delphi, if you know those points, and do not abuse of memory manager calls or string process in your threads.

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe
Rectangle 27 0

Since your question is understandably high level, I'm going to provide a high level answer which should point you in the right direction. If you then have more specific questions, please first check if someone else has already asked the question; if not then feel free to ask a new question.

Whenever you implement a thread, you have full control over what the thread does. So yes, if your thread execute method simply performs a calculation then ends, your thread will terminate. If you want to keep your thread active, just make sure the method doesn't end.

The easiest way to do this would be to use while True do;. WARNING Putting your thread into a simplistic infinite loop like this is actually very bad because it introduces some serious problems. You do need an infinite loop to keep the thread active for multiple calculations as they become available; however, you'll need additional code to resolve the following problems.

  • This can be done by using a Windows API call (or Delphi equivalent) that tells the thread to stop until something else happens.
SleepEx
WaitForSingleObject
TSimpleEvent
  • So the first thing you'd want to change in your loop is that instead of while True, you should rather use while not Terminated. This way anything that has a reference to your thread can set a flag telling your thread it must exit its loop (thereby terminating) as soon as it's appropriate to do so.
  • Note that if your thread is paused (as per the earlier problem), you must also ensure that setting this flag wakes the thread up to actually check the flag. So you can add to your earlier reading list: WaitForMultipleObjects.
  • Basically, you'll need to maintain a list of input data structures. Whenever you receive new data, you add a structure to the list. The thread will remove items from the list as it processes them. (This list would ordinarily be a Queue or FIFO collection.)
  • Whenever one or more items are added to the Queue, the wake-up event must be triggered so the thread can start processing again. The thread should process all items currently in the Queue before going back to sleep.
  • NB! It is absolutely essential that your Queue implementation be thread safe. You don't want concurrent adding and/or removing to corrupt your internal structures.
  • Suggested reading: Message Queues, PostMessage (sends a message to a standard Windows message queue) and Command design pattern.

You seemed concerned about the time overhead of creating a thread. This suggests your calculations are themselves actually quite fast. This begs the question, are you really gaining anything by using a separate thread to do your calculations?

You did also say that your input data already comes from different threads. So if your calculation involves correlating data from multiple source threads, then it does make sense. I only mentioned this because it's an all too common programming misconception that multiple threads can speed up a program. And if the calculations are fast there's absolutely no point in moving to another thread to do the same work.

multithreading - Backgroundworking Thread Delphi 2010 - Stack Overflow

multithreading delphi udp delphi-2010 indy
Rectangle 27 0

In C++Builder 6 and Delphi 7 onwards, the File > New > Other > Thread Object wizard has an option for naming the new thread in the debugger. The wizard generates a stub TThread descendant class with the necessary RaiseException() implementation at the top of its Execute() method.

That is not any help for Delphi 6 though, which did not support thread naming yet.

I just tried that and the only thing in the generated Execute() method was the comment "Place thread code here".

Also, I just tried Serg's code, which only seems to differ from the snippet I posted by the use of PAnsiChar(AnsiName) instead of PChar(Name), and I still don't see the thread names (Delphi 6).

Apparently it was not implemented until Delphi 7, sorry.

multithreading - Is this the correct way to set a thread's name in Del...

multithreading delphi exception-handling
Rectangle 27 0

Remy explained the problems... I've wanted to do this in Indy for a while so I posted a possible solution that I just put together to a new Google Code project instead of having a long comment here. It's a first-stab sort of thing, let me know if you have some changes to integrate: https://code.google.com/p/delphi-vault/

This code has two ways to Ping...multi-threaded clients as in your example, or with a simple callback procedure. Written for Indy10 and later versions of Delphi.

Your code would end up using a TThreadedPing descendant defining a SynchronizedResponse method:

TMyPingThread = class(TThreadedPing)
  protected
    procedure SynchronizedResponse(const ReplyStatus:TReplyStatus); override;
  end;
procedure TfrmThreadedPingSample.butStartPingClick(Sender: TObject);
begin
  TMyPingThread.Create('www.google.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.shouldnotresolvetoanythingatall.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.microsoft.com');
  TMyPingThread.Create('127.0.0.1');
end;

The threaded response is called in a synchronized method:

procedure TMyPingThread.SynchronizedResponse(const ReplyStatus:TReplyStatus);
begin
  frmThreadedPingSample.Memo1.Lines.Add(TPingClient.FormatStandardResponse(ReplyStatus));
end;

Wouah, you dit a lot of work. Great answer. Right now I'm modifying my code to use your implementation. Perhaps 2 comments. Fist one is to add/modify to be have somewhere a boolean answer of the pingReply. As in my case I just want to know yes/no is the computer connected. Another thing is that your code can interest many people and right now it is specific to my needs : defReceiveTimeout = 200; and defIPVersion = Id_IPv4; the user should be able to change these value to match his specific need (did you try ipv6 ? is it working).

+1, nice hit to make a shared place for StackOverflow projects! That brings me an idea to make my personal one and always share the whole project since I usually (almost always) test the stuff I'm posting, so now I'll just commit the full project to that personal storage and include also a link to the full project to the answer.

@Darian I have read your code carefully. Can you confirm me that I understood it correctly. The main idea in your code is to send multiple ping thread but get all the reply in the same procedure (InternalHandelReply), using SequenceId to know which is which. That way of doing (also as Remy said) also to treat every reply without discarding any of them and therefore treating them all ? Am I correct ? ...

... because in fact the result is not that much different than my "no thread code". In my case the ping response when not connected is about 3 seconds. What I was expecting was to have ALL the replies after 3 seconds. In the current code I have to wait for each computer for 3 sec, 60 PC = 3 minutes which is too long .. I am, looking for a way of getting the 40 replies at once and parse through them. The idea of @Remy of have 60 thread all replying to the same single replythread is what I am trying to do, so I can parse the replies manually with the sequenceID (do you understand what i mean)

Note that I corrected the data. I have 40 computers and 20 oscilloscopes (windows CE based) that's 60 devices not 40 as I first said.

multithreading - Delphi (XE2) Indy (10) Multithread Ping - Stack Overf...

multithreading delphi ping indy tthread
Rectangle 27 0

[You can set thread name: TThread.NameThreadForDebugging.] (implemented in D2010 as David pointed out)

You can create anonymous thread (a thread that executes anonymous function and doesn't need a TThread descendant object): TThread.CreateAnonymousThread.

Ironic that if naming threads is so handy, that anyone would want to create an anonymous thread object that doesn't even have a function associated with it since it's just a closure (a block of code inside another function). Personally I want all my background thread code to be running from inside a class that descends from TThread.

@Warren Is there a reason for that desire?

Warren, nobody is stopping you :) However, there are times when a anonymous background worker suffices.

The reason for that desire is that debugging threads is painful enough without anonymous threadlets.

@WarrenP Why do anonymous procs make debugging harder? You can still break in them.

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe
Rectangle 27 0

TThreadedQueue was introduced in XE.

I find it useful for passing information from worker threads to the main thread or other consumer threads. The last part, having multiple consumer threads, was buggy unfortunately. There was a bug in TMonitor, a class introduced by Delphi 2009, used to synchronize access to the queue in TThreadedQueue.

What is new in multithreading in Delphi XE? - Stack Overflow

multithreading delphi delphi-xe