startThread and synchronized usage

Find and share HowTos to various installations / configurations!
Search

Post Reply
8 posts • Page 1 of 1
arunvalakottial
Posts: 3
Joined: Tue Nov 05, 2019 8:24 am

startThread and synchronized usage

Post by arunvalakottial » Tue Nov 05, 2019 8:32 am

I am having trouble understanding how startThread and synchronized work.

Here is my sample code:

const int COUNT = 10;
global int g_count = 0;

synchronized int synchronizedFunction()
{

delay(0, 100); // Delay introduced to simulate some time consuming operation
++g_count ;
return g_count ;
}

void functionA()
{
for (int i = 0 ; i < COUNT ; ++i)
{
int val = synchronizedFunction();
DebugTN(__FUNCTION__ + " Thread id : " + getThreadId() + " Current count : " + val);
}
}

void functionB()
{
for (int i = 0 ; i < COUNT ; ++i)
{
int val = synchronizedFunction();
DebugTN(__FUNCTION__ + "Thread id : " + getThreadId() + " Current count : " + val);
}
}

main(mapping event)
{
int res1 = startThread("functionA");
DebugTN("res1 = " + res1);
int res2 = startThread("functionB");
DebugTN("res2 = " + res2);
}


I am expecting that both the threads execute simultaneously i.e. functionA and B get executed together. However the output shows that first functionA executes completely then functionB executes.

Any idea what am I doing wrong?

dvribeira
Posts: 15
Joined: Mon Mar 18, 2019 10:53 am

Re: startThread and synchronized usage

Post by dvribeira » Tue Nov 05, 2019 8:42 am

I think this is what's happening:
Since WinCC OA does not support real multithreading in CTRL, it will only execute the code on a single logical core, this is well documented. When you create your threads in CTRL, these are managed and scheduled by WinCC OA to share the processing time of the single-threaded manager. Since both of your threads are calling a synchronized function where you have a delay, only one of them at a time can call it. If you put a delay within the for loop of A and B you will see that they will take over... I think you can tweak some things of the scheduler like the maximum number of instructions a CTRL thread can execute... other than that you will have to ask ETM for more details on the scheduler.

arunvalakottial
Posts: 3
Joined: Tue Nov 05, 2019 8:24 am

Re: startThread and synchronized usage

Post by arunvalakottial » Tue Nov 05, 2019 11:23 am

Thanks for the the reply!

I found that if instead of having the whole function as synchronized, I had synchronized the block instead and moved the delay out of it... i.e.

int synchronizedFunction()
{

delay(0, 100); // Delay introduced to simulate some time consuming operation
synchronized(g_count)
{
++g_count ;
return g_count ;
}
}

The threads end up executing simultaneously(virtually)...

Another change I tried:

int synchronizedFunction()
{

delay(0, 100); // Delay introduced to simulate some time consuming operation
synchronized(g_count)
{
delay(0,100); // Another delay
++g_count ;
return g_count ;
}
}

In this case also, the output indicates that threads are executing simultaneously (virtually)...

Not sure why such a behavior though

dvribeira
Posts: 15
Joined: Mon Mar 18, 2019 10:53 am

Re: startThread and synchronized usage

Post by dvribeira » Tue Nov 05, 2019 1:11 pm

Ok, take the next lines with a huge grain of salt, since it is just my understanding of how things work, but it might be wrong...

I think it is because delays allow the WinCC OA thread executing it to be interrupted. In the case you described when you opened the case, when the delay is part of the synchronized block, even if the thread A (let's say) is interrupted, thread B cannot do anything because it wants to access a synchronized block of code which is locked by another thread (because even if the thread is waiting because of the delay, it is still locking the synchronized block until the delay is finished, the delay function returns and the other statements are executed). Then when A comes back and finishes execution it continues uninterrupted and is "allowed by the WinCC OA scheduler" (no clue how that is actually implemented) to continue execution and enters again the synchronized block.

Now, if the delay is out of the synchronized block, threads get interrupted so the other one can kick in because the synchronized block is not locked at the moment. Now if you have 2 delays, it is only the one outside the synchronized block doing the trick (it allows the thread to be interrupted and the other one can access the synchronized block because this one didn't enter it yet), because the inner one will also allow for an interruption but it will still be the former case in which the synchronized is locked and B can't access it.

Also and related to the interruption implications of delay(), whenever you have a potentially blocking operation (a huge loop for instance), in which you can get the annoying "no heartbeat" message from WinCC OA, it is enough to put a delay(0) at the end of the loop so the thread is interrupted, even if it will resume execution immediately because there is no other thread to execute stuff.

Cheers,
Daniel
Last edited by dvribeira on Fri Nov 08, 2019 7:43 am, edited 1 time in total.

arunvalakottial
Posts: 3
Joined: Tue Nov 05, 2019 8:24 am

Re: startThread and synchronized usage

Post by arunvalakottial » Wed Nov 06, 2019 3:46 am

Thank you... I now understand why the behavior is happening thanks to your detailed explanation... also the delay(0) trick that you suggested was really helpful as now I can kind of guarantee a context switch when working with threads.

User avatar
leoknipp
Posts: 1985
Joined: Tue Aug 24, 2010 5:28 pm

Re: startThread and synchronized usage

Post by leoknipp » Thu Nov 07, 2019 3:15 pm

Using a delay(0); is not a good idea.
The information given in the posting viewtopic.php?f=16&t=10817#p966301 is correct.

WinCC OA Control is not really multi threaded.
You can start several threads but only 1 thread at a specific time is processed. WinCC OA switches then between the threads to execute threads "in parallel".
Thread switching is done automatically and there is no real possibility to control it.
With the config entry ctrlMaxWeight you can have an influence on processing CTRL threads.
For details please have a look at the WinCC OA Documentation and search for "ctrlMaxWeight".

Best Regards
Leopold Knipp
Senior Support Specialist

User avatar
kilianvp
Posts: 196
Joined: Fri Jan 16, 2015 9:29 am

Re: startThread and synchronized usage

Post by kilianvp » Fri Nov 08, 2019 8:27 am

does CTRL++ work the same way? is a thread started for each instance of a class and WinCC OA switches between the threads?

User avatar
leoknipp
Posts: 1985
Joined: Tue Aug 24, 2010 5:28 pm

Re: startThread and synchronized usage

Post by leoknipp » Fri Nov 08, 2019 8:47 am

CTRL++ is also not multi threaded as it is still CTRL and running in the same WinCC OA process which is not multi threaded.

Best Regards
Leopold Knipp
Senior Support Specialist

Post Reply
8 posts • Page 1 of 1