Recent

Author Topic: Strange, MutiThreads limitation?  (Read 2168 times)

senglit

  • Full Member
  • ***
  • Posts: 131
Strange, MutiThreads limitation?
« on: July 15, 2019, 04:58:20 pm »
Hi all,

I am developing a software with lazarus to control some industrial equipments (via RS485/232). I need to check the equipment state very frequently (each 200ms). Concidered potential equipment failures (at this kind of situation, the RS485/232 device wouldn't reply untill the time out), I used several TThreads, each for one RS485 device connection.

So, the program looks like this:

...
.....
TMainForm = class(TForm)
MyCom:array of TComThread;
MyComAccount:integer=0;

TMainForm.CreateRS485Dev;
begin
(if find a new RS485 from the configuration file) then
inc(MyComAccount);
MyCom[MyComAccount-1]:=new TComThread(true);
//some parameter configuration to this thread
MyCom[MyComAccount-1].resume;
end;

TMainForm.HandleMsg(Msg:PtrInt)
begin
//Show the information on the Main Form UI
dispose(PMyInfoType(Msg));
end;
..............

TComThread = class (TThread)
.
.
procedure TComThread.Execute;
var
  i:integer;
begin
  While not Terminated do
  begin
    for i:=0 to SurvCmdCount - 1 do DoRutineSurv;
    Sleep(200);
  end;
end;

procedure TComThread.DoRutineSurv;
begin
  //...Read 1 piece of information from the RS485 Device...
   Application.QueueAsyncCall(@MainForm,HandleMsg, PtrInt(Information));  //send the information to MainForm to show
end;

When I get no more than 4 RS485 devices, this program works well. But when I get my fifth devices, the thread MyCom[4] can never run to the procedure "DoRutineSurv". It was just been created and stayed there doing nothing! I tried to add the sixth device, the result was the same. But the threads MyCom[0] to MyCom[3] worked!

Since the first 4 threads works well. I think this program structure should be OK. I guess there must be some "switch" to config something to make threads whose id is larger than 3 to work. But I just don't know how to do it.

Is there anybody know the solution? Thanks in advance!

Senglit
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

senglit

  • Full Member
  • ***
  • Posts: 131
Re: Strange, MutiThreads limitation?
« Reply #1 on: July 15, 2019, 05:17:27 pm »
PS: this multi-thread program is developed on win7 with lazarus 2.0.0. Run on win7/win10
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Strange, MutiThreads limitation?
« Reply #2 on: July 15, 2019, 05:24:30 pm »
https://www.freepascal.org/docs-html/rtl/classes/tthread.queue.html would be the way to go, unless it is critical that the display needs to be in 200 Ms resolution as well.
The timing for display is not critical anyway, unless you have an extremely high hardware spec. You should have realized that the RS interfaces are serial anyway.

It looks like you are running just four cores...?

[edit]
So there are two solutions:
- 1. Do the above
- 2. Buy more cores.

There is nothing obviously wrong with your code.
« Last Edit: July 15, 2019, 05:32:37 pm by Thaddy »
Specialize a type, not a var.

julkas

  • Guest
Re: Strange, MutiThreads limitation?
« Reply #3 on: July 15, 2019, 06:13:20 pm »
You can test  your software with Virtual Ports emulator also.

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: Strange, MutiThreads limitation?
« Reply #4 on: July 15, 2019, 07:19:48 pm »
I think, Thaddy is right.
On the other side I think, a thread, reading from a serial device should not consume a lot of CPU time.
Most time such a thread should sleep and so the amount of threads should not matter much.
Windows runs some 100 threads or some 1000 in the background!
So I think,  your threads contain a busy waiting loop that consumes much more CPU time than necessary.

Possibly use the performance monitor to find which thread consumes how much CPU.

julkas

  • Guest
Re: Strange, MutiThreads limitation?
« Reply #5 on: July 15, 2019, 07:24:48 pm »
I have some experience with RS485/232 communication, but I never used threads.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Strange, MutiThreads limitation?
« Reply #6 on: July 15, 2019, 11:08:53 pm »
Using threads this way on a single serial port isn't going to cut it..

You need to have a single thread process a single port and have it send a notice to your main thread when
it completes.

 Your main thread will then send another request which would be the next device in line,..

 You could also tie the Serial thread to a class where it can handle all the devices automatically when it
completes each one..

 But trying to have a thread for each device talking to a single port isn't going to work that way...

 I've written Modbus interfaces, I know..
The only true wisdom is knowing you know nothing

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Strange, MutiThreads limitation?
« Reply #7 on: July 16, 2019, 12:16:04 am »
Try to change
Code: Pascal  [Select][+][-]
  1. Sleep(200);
to
Code: Pascal  [Select][+][-]
  1. Sleep(150);
and report if you can now run 5th thread (but do not try to run more threads then that).
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: Strange, MutiThreads limitation?
« Reply #8 on: July 16, 2019, 06:02:17 pm »

Concidered potential equipment failures (at this kind of situation, the RS485/232 device wouldn't reply untill the time out), I used several TThreads, each for one RS485 device connection.


If there is a busy waiting loop is in the RS485 driver, then you are out of luck, unfortunately.

Anyway there is something strange: In Windows it is possible to start e.g 22 threads, that factorize a large number, so all threads are always busy, and the windows scheduler gives each thread an equal chance to run - they all run with equal speed.
CPU load is 98% under this circumstances, the fan becomes louder, but the gui surface stays responsive.
According to Taskmanager windows ran 191 processes and 2409 threads, so at average each process has more than 10 threads.
I tried this some minutes before I wrote this, Windows 10 64 bit, AMD Phenom, 6 cores.

So the question is: is this on windows or on something else?

If this is on windows and if the threads have normal priority then under all circumstances then

 TComThread.DoRutineSurv()

should get an opportunity to run in each thread.

If you use a hard realtime os, then you must not use busy waiting at all, this will burn CPU time that other threads need and block other threads from running.
« Last Edit: July 17, 2019, 07:19:29 am by Peter H »

senglit

  • Full Member
  • ***
  • Posts: 131
Re: Strange, MutiThreads limitation?
« Reply #9 on: July 18, 2019, 03:09:23 pm »
Thanks to everybody for your help. After reading all of your suggestions, I did something and here are some information you may be interested in.

1. I get only 4 cores. It may limite the efficiency when I use more than 4 threads, but I guess it would not limite the threads count.
2. I tried to change the sleep time as avra said. it turned out that the 5th thread worked! how strange it is! So I guess the fifth thread was just no luck to get the chance to run. When the sleep time changed, and each thread's survey commands number were different, the fifth thread got its chance.
3. I think Thaddy is right. RS is always seriel, there is no need to create so many threads to handle each device, epsecially when some COMs are acturally connected to a COM485 Hub, they share 1 COM port of my PC! So I merge all of the threads to one. it works properly.

Thanks again for all the help from you!

Senglit
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Strange, MutiThreads limitation?
« Reply #10 on: July 18, 2019, 03:44:40 pm »
2. I tried to change the sleep time as avra said. it turned out that the 5th thread worked!
My guess was that your threads are not properly written, and that they have some interlock. Four threads worked because 4x200ms < 1 sec. When you created another thread 5x200ms >= 1s, and 5th thread has never really started. That's why I told you to change 200ms to 150ms to see if there is room for another thread. I guess that you can now try 120ms instead of 150ms and see how many threads can work in parallel. If that number is 8 or less then you probably have a lock you are not aware of. Number of cores has nothing to do with number of threads you can start, because OS takes care of sharing the cores between threads.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Strange, MutiThreads limitation?
« Reply #11 on: July 18, 2019, 04:37:38 pm »
Note you can adjust the thread local stack size for threads, that's also a limitation on some platforms. 1 MB is usually enough.
Specialize a type, not a var.

 

TinyPortal © 2005-2018