Execution of Multiple Threads

Saj

Active Member
Licensed User
Does basic4ppc support the execution of multiple threads, e.g. Worker Threads in C#?

I have resource hungry subs which when executing 'lock up' the user interface until the sub has finished. I'd like the GUI to be responsive regardless of what calculations are carried out in the background.
 

Saj

Active Member
Licensed User
1. I have a timer ticking away every second in the main GUI thread calling a number crunching thread. How does b4ppc and .Net behave when the number crunching thread hasn't had enough time to complete before the next call from the main GUI thread?
Do the calls stack up or is the latest call ignored since the earlier call to the number crunching thread hasn't yet been completed?

2. Can i get away with not using a LockFlag to only READ a global array in the number crunching thread? The global array is populated on every timer tick in the main GUI thread.
 

Saj

Active Member
Licensed User
Thread Crash

I have a common array shared by the main GUI thread and 2 other threads - see attachment.

A lock is used to control write access to the array. A problem occurs when ToolBar_Click attempts to lock the array, the GUI sometimes freezes until trackArrLock.WaitFor(10000) fires. This then causes and 'exception' error.

I have tried the following to determine the cause of the error:
(a) commented out calls to ThreadEvent and DebugEvent
(b) commented out the lines in the 2 thread subs which write to the array to check that the array isn't being written to from more than 1 place

None of the above had an impact, which would suggest that the structure as outlined in the attachment is maybe not quite right? Any suggestions?:sign0085:
 

agraham

Expert
Licensed User
Longtime User
The GUI will freeze until trackArrLock.WaitFor(10000) or trackArrLock.Wait returns as Timer and Control events are raised in the message loop and so run on the main GUI thread. You don't however tell us what exception you get :( and your diagram shows only Wait and not WaitFor calls from the moveJPG and toolbar_Click Subs. The call from moveJPG has a parameter so I guess this one at least is a WaitFor call.
 

Saj

Active Member
Licensed User
Thanks for the reply agraham. The error msg is attached.

The GUI will freeze until trackArrLock.WaitFor(10000) or trackArrLock.Wait returns as Timer and Control events are raised in the message loop and so run on the main GUI thread.
I don't quite understand this since GUI freezing does not always occur when Sub Toolbar_Click is called. Also the Sub ThreadZoom takes much less than 1 sec to execute when it doesn't crash with trackArr having less than 50 elements.

I have attached the subs in question. I haven't included the whole sbp file as its too big.
 

Saj

Active Member
Licensed User
I've tried replicating the problem on a smaller executable, but me program's got too many calls to files, subs etc to do that simply. I've reduced the size of the sbp file with the relevant subs to less than 100 lines hoping that makes scanning the code easier.:)
 

Attachments

  • ThreadDebug2.sbp
    5 KB · Views: 343

agraham

Expert
Licensed User
Longtime User
One obvious thing I can see is that Sub captureTrackPoint doesn't use the return from WaitFor and so doesn't know whether it has gained the lock or not. I don't know how or when captureTrackPoint is called but if it is from the main thread then I would not use WaitFor with such a long timeout. I'd probably check with a timer using WaitFor(0) to avoid slowing the GUI.

Otherwise it looks OK but as there isn't the whole program structure there to see what is calling what I can't see what might be happening.

Threading problems are notoriously difficult to resolve because of their inherent asynchronicity. I suggest that you mock up a small app that uses the same locking logic as your main application but with much simpler code. You can then put loops in the different subs to simulate their processing time and see if you can replicate the effect. If you can get a small runnable program that demonstrates the effect and you still can't see why then I could take a look at that for you.
 

Saj

Active Member
Licensed User
I've put together a cut down version with the exisiting locks. When running the program:
1. let trackArr array fill up with around 100 elements to load the processor
2. in QUICK succession press the reduce zoom button
3. program should crash
4. I have also attached an intermittent 'drawing' error I haven't been able to bottom out which may occur.
 

Attachments

  • ThreadDebug3.zip
    7.5 KB · Views: 295

agraham

Expert
Licensed User
Longtime User
I have already pointed out the main problem in the post above. You are using WaitFor and not checking that you have a lock and then running on and calling Reset when the lock isn't yours. Also you risk a deadlock caused by ThreadCalcTrackXYCoords calling FireThreadEvent, which needs to run on the main thread from the message loop when the main thread is waiting for the lock so if you have to wait for a lock in the main thread then you should do this.
B4X:
Do
    res = trackArrLock.WaitFor(0)   
    If Not(Res) Then
        DoEvents
    End If 
    Loop While Not(res)
I've seen the pen error when running in the IDE but not when compiled. As long as it works when compiled I wouldn't be too worried as Threading in the IDE, which is interpreted, is something that the IDE wasn't designed to support so it's a bit of a miracle that it works as well as it does.
 

Saj

Active Member
Licensed User
Many thanks - that sorted it out.:)

Also you risk a deadlock caused by ThreadCalcTrackXYCoords calling FireThreadEvent, which needs to run on the main thread from the message loop when the main thread is waiting for the lock so if you have to wait for a lock in the main thread then you should do this.
Can u plz elaborate on this a bit more. Reading the Threading help files I understand a thread can update the GUI via event calls (i.e. FireThreadEvent)?

Q: when a thread has a lock, will the thread still be time sliced allowing GUI thread activites to carry on unhindered? The Threading help file states 'LockFlag object which allows a thread to complete, uninterrupted, non-atomic activities'?
 

agraham

Expert
Licensed User
Longtime User
All Basic4ppc events run on the GUI thread. If you stop the GUI thread by waiting on a lock thread events cannot run so your program can hang because the thread is waiting for the the GUI thread to run the event and the GUI thread is waiting for the other thread to release the lock.

Holding a lock has no effect upon timeslicing of the thread holding it, a thread is either running normally, being timesliced, or supended waiting on a lock.
 

Saj

Active Member
Licensed User
Is possible to change the Priority of a thread once the program is executing? I get the following error when attempting to change the priority ( I first check that the thread is not running):

"Thread is dead; priority cannot be accessed"
 
Top