What's the difference between Thread.Sleep() and Thread.SpinWait() - multithreading

I have a WinForm application that uses a BackGroundWorker to create a TCP Client and send some data to a remote server.
When the socket finish close the connection and the BGW exits from the DoWork Sub.
In the RunWorkerCompleted Sub I must to wait a packet from the remote server, so I have always running a TCP server that fills a Friend String type variable and indicates that the whole packet is received using a Boolean type variable(flag).
So I must to wait that flag to becomes True to process the data that must be in the String type variable; but I don't want to hang up the GUI so I see that exist a method called SpinWait.
So, Can this code works?
There's any way to get out if the loop if the flag doesn't to true 5 minutes later?
Private Sub BGW1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW1.RunWorkerCompleted
While Not AckReady
System.Threading.Thread.SpinWait(500)
End While
'Here process the received data from TCP server
TmrReport.Start()
End Sub
Another things is, How many iterations represent 500mS?

Per the documentation:
Thread.SpinWait Method
The SpinWait method is useful for implementing locks. Classes in the .NET Framework, such as Monitor and ReaderWriterLock, use this method internally. SpinWait essentially puts the processor into a very tight loop, with the loop count specified by the iterations parameter. The duration of the wait therefore depends on the speed of the processor.
Contrast this with the Sleep method. A thread that calls Sleep yields the rest of its current slice of processor time, even if the specified interval is zero. Specifying a non-zero interval for Sleep removes the thread from consideration by the thread scheduler until the time interval has elapsed.
So, Sleep basically releases the processor so it can be used by something else, whereas SpinWait runs a loop that keeps the processor busy (and locked to other threads).

Related

Forcing a message loop to yield

I hope this question isn't too broad.
I'm working with a legacy Ada application. This application is built around a very old piece of middleware that handles, among other things, our IPC. For the sake of this question, I can boil the middleware's provisions down to
1: a message loop that processes messages (from other programs or this program)
2: a function to send messages to this program or others
3: a function to read from a database
The program operates mainly on a message loop - simply something like
loop
This_Msg := Message_Loop.Wait_For_Message; -- Blocking wait call
-- Do things based on This_Msg's ID
end loop
however there are also callbacks that can be triggered by external stimuli. These callbacks run in their own threads. Some of these callbacks call the database-reading function, which has always been fine, EXCEPT, as we recently discovered, in a relatively rare condition. When this condition occurs, it turns out it isn't safe to read from the database when the message loop is executing its blocking Wait_For_Message.
It seemed like a simple solution would be to use a protected object to synchronize the Wait_For_Message and database read: if we try to read the database while Wait_For_Message is blocking, the read will block until Wait_For_Message returns, at which point the Wait_For_Message call will be blocked until the database read is complete. The next problem is that I can't guarantee the message loop will receive a message in a timely fashion, meaning that the database read could be blocked for an arbitrary amount of time. It seems like the solution to this is also simple: send a do-nothing message to the loop before blocking, ensuring that the Wait_For_Message call will yield.
What I'm trying to wrap my head around is:
If I send the do-nothing message and THEN block before the database read, I don't think I can guarantee that Wait_For_Message won't have returned, yielded, processed the do-nothing message, and started blocking again before the pre-database read block. I think I conceptually need to start blocking and THEN push a message, but I'm not sure how to do this. I think I could handle it with a second layer of locks, but I can't think of the most efficient way to do so, and don't know if that's even the right solution. This is really my first foray into concurrency in Ada, so I'm hoping for a pointer in the right direction.
Perhaps you should use a task for this; the following would have the task waiting at the SELECT to either process a message or access the DB while another call on an entry during the processing would queue on that entry for the loop to reiterate the select, thus eliminating the problem altogether... unless, somehow, your DB-access calls the message entry; but that shouldn't happen.
Package Example is
Task Message_Processor is
Entry Message( Text : String );
Entry Read_DB( Data : DB_Rec );
End Message_Processor;
End Example;
Package Body Example is
Task Body Message_Processor is
Package Message_Holder is new Ada.Containers.Indefinite_Holders
(Element_Type => String);
Package DB_Rec_Holder is new Ada.Containers.Indefinite_Holders
(Element_Type => DB_Rec);
Current_Message : Message_Holder.Holder;
Current_DB_Rec : DB_Rec_Holder.Holder;
Begin
MESSAGE_LOOP:
loop
select
accept Message (Text : in String) do
Current_Message:= Message_Holder.To_Holder( Text );
end Message;
-- Process the message **outside** the rendevouz.
delay 1.0; -- simulate processing.
Ada.Text_IO.Put_Line( Current_Message.Element );
or
accept Read_DB (Data : in DB_Rec) do
Current_DB_Rec:= DB_Rec_Holder.To_Holder( Data );
end Message;
-- Process the DB-record here, **outside** the rendevouz.
or
Terminate;
end select;
end loop MESSAGE_LOOP;
End Message_Processor;
End Example;

How to make WM_TIMER msg be called in ordered sequence in WinApi?

I'm doing winapi programming and i usually have a problems related to WM_TIMER msg: for example, when i put function that activates when WM_TIMER msg is called, like Update() function for example, this function is still called even though i killed timer. What's the main problem right now is that when i believe that i deleted the class that contain Update() function, this class still calls Update() function even though i killed timer and this class first, and because of this, i get memory error because this Update() function deals with attributes that are already deleted in previous delete function. Is there any solution to make WM_TIMER be called after certain task is done?
The WM_TIMER message is actually a flag -- when some timer expires, the flag is set to generate a single WM_TIMER event if the message queue is empty and GetMessage is called.
This avoids clogging up the system with many WM_TIMER messages and collapses multiple expired timers into one, but has the disadvantage of delivering the WM_TIMER message after all other messages (WM_PAINT is treated similarly).
So what you are seeing is that the timer you have killed has already elapsed and the flag is set, but the message will not be delivered until your program is otherwise idle.
You want to keep a flag to memorize whether you are actually waiting for a timer event.
In an application with multiple timers in parallel you'd keep a list of active timers, and use the Windows timer mechanism to schedule the next timer to elapse, and in the handler, invoke all sub-handlers whose deadlines are past.

VB6 callback Sub's relation to calling win32 thread, and vice versa

A function in a win32 process (call it void cCB()) calls a VB6 Sub (call it vb6S, which receives some numeric data type data from cCB. cCB originally received vb6S reference via AddressOf.
I've got two basic newbie questions about this:
Question 1: Is cCB's thread blocked by the call while vb6S() executes its code?
Question 2: Will VB have any "issues" if cCB's thread terminates and cCB's
memory is de-allocated before vb6S has completed its work?
EDIT:
In response to the request for code (and thanks for that downvote), here is the issue:
The task is a microsecond timer, to be used to unblock the WM queue of two VB IDE's when debugging two VB apps that are communicating via WM_COPYDATA messages.
That is: there are apps Alice and Bob. When Alice sends Bob a wm74 (WM_COPYDATA) message, Bob hooks on to it, saves the information in the copydatastruct, and then is finished with the message. The problem is that, now, in debugging, both Alice's and Bob's message queues are blocked as long is either debugger is at a break point. It doesn't take long to kill one or both IDE's at that point.
So what I want to implement is an old Java Applet trick: Bob calls out of process, which waits a tiny slice of time, and calls back in. While out of process, Bob can release the message, the app/IDE tells Windows the message is handled, and Alice can go about her business. To do this, before returning, Bob's message handler calls into a win32 DLL function, say:
typedef void (__stdcall *FUNCPTR)(int);
void __stdcall ExecuteCallback(FUNCPTR cbAddress, double microS){};
which Bob calls as
ExecuteCallback AddressOf My74Processor, 250
where My74Processor contains the app logic to process the string according to the cases in the code number that Alice put in the message structure.
ExecuteCallback grabs an existing timingWork code object from a queue of those, and puts it into a queue of threads via a workQueue manager that knows to start the thread at the proper point in the timingWork class.
After the timingWork timer clocks 250 microseconds (in this case) via watching QueryPerformanceCounter, it calls back to Bob's Sub at
Sub My74Processor(ByVal reason as Long)
and terminates. The timingWork object is not destroyed; the last thing it does is put itself back in the queue of available objects. The thread, on the other hand, terminates, and is available in the thread queue for more, maybe different, work when its turn comes around again.
Back with Bob, there is a breakpoint set in the processing code down in Sub My74Processor. My questions, then, are in this context:
(a) when that breakpoint is hit, and the programmer takes some time to check variables and logic, and then continues the process, will all be fine in Bob's IDE's stack after My74Processor ends?
(b) when the timingWork routine makes the call back, will that thread be blocked?
I'm virtually certain the answer to (b) is "no." I'm worried about, and not experienced enough with VB6 to know the answer to that.
EDIT2 #wqw, I came to the same conclusion as I was going to sleep last night, but not for the correct reasons you state in your comment.
How about this: use the same out of process call, only instead of a callback function, send cCB information for it to send a WM_COMMAND message to VB6S, spoofing a state change of one of its controls, say a button, butCB? Then ExecuteCallback(..) becomes ExecuteClickback(..)
void __stdcall ExecuteClickback(WORD butID, HANDLE hBut, HANDLE hVB6S, double microS){};
The timerWork object does a PostMessage of a WM_COMMAND to hVB6S's Form with:
wParam = (DWORD) ( (butID << sizeof(WORD)) + (WORD) BN_CLICKED ); lParam = hBut;
Then, VB6S's form should raise its butCB_Click() event. That event handler would have the instruction to call My74Processor(). Since VB6S is necessarily in a pure message wait state once the call to ExecuteClickback is made, the arrival of the WM_COMMAND should "look" to VB6S just like the user actually clicked the button.

Is safe and good design AllocateHWND to respond more than one thread?

It's known that, in cases when one needs comunicate between UI thread and working thread, an hidden window must be created because of thread safety(handle reconstruction).
For exemplify:
Form1 has N dynamicaly created TProgressBar instances with the same name of a background running .
Is always garanteed that WM_REFRESH will only be called inside Task Thread.
Form1 has H : THandle property that allocates the following procedure:
procedure RefreshStat(var Message: TMessage); message WM_REFRESH;
Inside RefreshStat, in cases when there is only 1 background thread I could easily use L and W parameter to map Task Id and position.
I don't know if the title says what I want to know, but let's imagine if we have an application that has multiple background tasks running.
In my case I use TProgressBar to report progress the done.
Does AllocateHwnd garantee that all messages arrives with no race condition the hidden window?
What happens if two or more tasks post the message at the same time?
If this needs to be controled manually, I wonder if there is something else to do besides creating another message loop system in the custom message.
I hope the question is clear enough.
The message queue associated with a thread is a threadsafe queue. Both synchronous and asynchronous messages from multiple other thread are delivered safely no harmful date races. There is no need for any external synchronization when calling the Windows message API functions like SendMessage and PostMessage.
If two threads post or send messages to the same window at the same time, then there is no guarantee as to which message will be processed first. This is what is known as a benign race condition. If you want one message to be processed before the other then you must impose an ordering.

How to do asynchronuous programming in Delphi?

I have an application, where most of the actions take some time and I want to keep the GUI responsive at all times. The basic pattern of any action triggered by the user is as follows:
prepare the action (in the main thread)
execute the action (in a background thread while keeping the gui responsive)
display the results (in the main thread)
I tried several things to accomplish this but all of them are causing problems in the long run (seemingly random access violations in certain situations).
Prepare the action, then invoke a background thread and at the end of the background thread, use Synchronize to call an OnFinish event in the main thread.
Prepare the action, then invoke a background thread and at the end of the background thread, use PostMessage to inform the GUI thread that the results are ready.
Prepare the action, then invoke a background thread, then busy-wait (while calling Application.ProcessMessages) until the background thread is finished, then proceed with displaying the results.
I cannot come up with another alternative and none of this worked perfectly for me. What is the preferred way to do this?
1) Is the 'Orignal Delphi' way, forces the background thread to wait until the synchronized method has been executed and exposes the system to more deadlock-potential than I am happy with. TThread.Synchronize has been re-written at least twice. I used it once, on D3, and had problems. I looked at how it worked. I never used it again.
2) I the design I use most often. I use app-lifetime threads, (or thread pools), create inter-thread comms objects and queue them to background threads using a producer-consumer queue based on a TObjectQueue descendant. The background thread/s operate on the data/methods of the object, store results in the object and, when complete, PostMessage() the object, (cast to lParam) back to the main thread for GUI display of results in a message-handler, (cast the lParam back again). The background threads in the main GUI thread then never have to operate on the same object and never have to directly access any fields of each other.
I use a hidden window of the GUI thread, (created with RegisterWindowClass and CreateWindow), for the background threads to PostMessage to, comms object in LParam and 'target' TwinControl, (usually a TForm class), as WParam. The trivial wndproc for the hidden window just uses TwinControl.Perform() to pass on the LParam to a message-handler of the form. This is safer than PostMessaging the object directly to a TForm.handle - the handle can, unfortunately, change if the window is recreated. The hidden window never calls RecreateWindow() and so its handle never changes.
Producer-consumer queues 'out from GUI', inter-thread comms classes/objects and PostMessage() 'in to GUI' WILL work well - I've been doing it for decades.
Re-using the comms objects is fairly easy too - just create a load in a loop at startup, (preferably in an initialization section so that the comms objects outlive all forms), and push them onto a P-C queue - that's your pool. It's easier if the comms class has a private field for the pool instance - the 'releaseBackToPool' method then needs no parameters and, if there is more than one pool, ensures that the objects are always released back to their own pool.
3) Can't really improve on David Hefferman's comment. Just don't do it.
You can implement the pattern questioned by using OTL as demonstrated by the OTL author here
You could communicate data between threads as messages.
Thread1:
allocate memory for a data structure
fill it in
send a message to Thread2 with the pointer to this structure (you could either use Windows messages or implement a queue, insuring its enque and dequeue methods don't have race conditions)
possibly receive a response message from Thread2...
Thread2:
receive the message with the pointer to the data structure from Thread1
consume the data
deallocate the data structure's memory
possibly send a message back to Thread1 in a similar fashion (perhaps reusing the data structure, but then you don't deallocate it)
You may end up with more than 1 non-GUI thread if you want your GUI not only live, but also responding to some input, while the input that takes long time to be processed is being processed.

Resources