0

I'm using RaspberryPi (3B+) Linux ARM IOT board which OS is Debian Stretch 9, and my console application is developed on .NET CORE 2.1.

My application is quite simple by just open several TCP connections to a remote server, after build my application (with symbol Linux ARM), I can see the output files include myApp, and myApp.dll. I've done lots of run via directly command line:

pi@raspberrypi:~/Desktop/myApp $ ./myApp

or:

pi@raspberrypi:~/Desktop/myApp $ dotnet ./myApp.dll

which both runs well, and the CPU via top (process name is myApp, while the latter is dotnet) are all less than 20.

Today I want to add my app to daemon for keep runing all the way, this is my daemon serivce file under /etc/systemd/system:

[Unit]
Description=myApp for controlling Tcp devices

[Service]
WorkingDirectory=/home/pi/Desktop/myApp
# 
ExecStart=/usr/local/bin/dotnet myApp.dll
Restart=always
# Restart service after 10 seconds if this service crashes:
RestartSec=10
SyslogIdentifier=myApp
# User=pi
[Install]
WantedBy=multi-user.target

after enable, start the service via systemctl command, I can see the app is running via top (the process name is dotnet), but now the CPU is quite high (for process dotnet) which is over 100.

Any idea for how the CPU rises, and is there a way to keep my process name back rather than dotnet?

  • well, you're executing /usr/local/bin/dotnet myApp.dll ... so, the command is dotnet with an argument of myApp.dll ... on the command line you execute myApp ... so, clearly there is something in that folder called myApp - can you execute /home/pi/Desktop/myApp/myApp instead? - as for CPU issue, I can't answer that – Jaromanda X Jul 16 '18 at 1:10
1

There are some issues with your systemd unit. I don't know if it causes the high load of the cpu but it is the first step to fix that.

The service has no dependencies so it will immediately start on boot up in parallel with such essential services like local file systems, swap devices, udevd, tmpfiles, sysctl etc. Nothing is initialized what it needs, in particular the network.target. So it is very likely that your service fails. You have specified to Restart=always. That it will do and if it fails again, then again. That could be one cause of cpu high load.

I cannot see why to use Restart=always. If you only want to ensure that the service is restarted if it fails with any reason then this is symptom fixing, not fixing the real cause. A service has to run without error and if it fails you get an error log and you have to fix it. Only fixing the symptom may result in endless loops with cpu high load. If you really need Restart= then have a look at man system.service if you find a better choice. It is said there:

Setting this to on-failure is the recommended choice for long-running services, in order to increase reliability by attempting automatic recovery from errors. For services that shall be able to terminate on their own choice (and avoid immediate restarting), on-abnormal is an alternative choice.

I would suggest to use this unit:

[Unit]
Description=myApp for controlling Tcp devices
Wants=network.target
After=network.target

[Service]
WorkingDirectory=/home/pi/Desktop/myApp
ExecStart=/usr/local/bin/dotnet myApp.dll
SyslogIdentifier=myApp

[Install]
WantedBy=multi-user.target

If it doesn't work you can try to use
Wants=network-online.target
After=network-online.target
but it delays startup so the first choice is network.target.

  • thank you Ingo, I'll update my script by your suggestion since it sounds reasonable. I've pasted an answer, and I think that is the root cause of CPU high. – Shawn Jul 16 '18 at 11:44
  • the reason why I choose Restart=always is because I've saw several my application crash, which is highly likely the .NET CORE is not stable on Pi3B(ARM64), do you have any similar experience on this? – Shawn Jul 16 '18 at 12:03
  • @Shawn No sorry, never used .NET. I've been grown up with linux and the command line ... – Ingo Jul 16 '18 at 12:28
0

Finally I found the cause is the code in Main:

static void Main(string[] args)
{
    //my business logic code
    //balabala
    while (true)
       Console.ReadLine();
}

that means in deamon mode, the Console.ReadLine() always can read a space and cause an infinite loop, which consumed the CPU, I'm not sure how that space coming?

  • Only a bug in your code ;-) As service there is no console your program can read from. Seems Console.ReadLine() is failing and the endless loop is immediately continued. For a quick test simply insert a sleep(1) into the loop. – Ingo Jul 16 '18 at 12:11
  • it's not failing but do read a space. now the infinite loop sleep is my solution now. – Shawn Jul 16 '18 at 12:13
  • You can delete the whole loop. There is nothing to do with ReadLine(). Even with sleep it is waste of resources. – Ingo Jul 16 '18 at 12:33
  • @Ingo I have another issue could you help to take a look? stackoverflow.com/questions/51491972/… – Shawn Jul 24 '18 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.