One copy of the program?

Linux specific forum
lakomet
User
User
Posts: 53
Joined: Mon Apr 04, 2011 3:56 am
Location: Russia,Angarsk

One copy of the program?

Post by lakomet »

Hi, how to prevent running multiple copies of the program?
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: One copy of the program?

Post by luis »

You can use a mutex (but I don't know how a mutex object is created on linux so you have to look up for that), also try to search for "single instance" in the forum (if you didn't do it, don't know if there are solutions for linux though).


Another idea:

http://www.linuxquestions.org/questions ... on-256693/
"Have you tried turning it off and on again ?"
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: One copy of the program?

Post by Foz »

The simplest cross platform method is to open a port (above 50000 as it's for temporary use) to listen on - it doesn't have to do anything with it, just open it on start, and close on exit.

If you fail to open the port, then your program is already running.
lakomet
User
User
Posts: 53
Joined: Mon Apr 04, 2011 3:56 am
Location: Russia,Angarsk

Re: One copy of the program?

Post by lakomet »

Foz wrote:50000 as it's for temporary use
You propose to use CreateNetworkServer (0, 50001)?
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: One copy of the program?

Post by wilbert »

Foz wrote:If you fail to open the port, then your program is already running.
Sounds like a big risk.
If there's any other reason that makes it fail, your program won't run at all.
lakomet
User
User
Posts: 53
Joined: Mon Apr 04, 2011 3:56 am
Location: Russia,Angarsk

Re: One copy of the program?

Post by lakomet »

wilbert wrote:Sounds like a big risk.
There is a risk, but each program has a preference file, it can record you are currently using the port (0-65000)?
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: One copy of the program?

Post by luis »

The risk lies in the fact you can be unable to open a port for various reasons, I would not do it that way.
"Have you tried turning it off and on again ?"
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: One copy of the program?

Post by Tenaja »

I know one way that has been common is to use a "program open" prefs file. The obvious disadvantage to that is the file stays in the "open" state in the event of a computer crash...but at least it is an easy fix to just delete it.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: One copy of the program?

Post by wilbert »

You could write a timestamp and update the timestamp every 5 minutes and delete the file when the app closes.
When you open the app, you search for the file containing the timestamp. If it isn't there or the timestamp was updated longer than five minutes ago, it probably isn't running.
By using a timestamp like this, an app that crashes will only be locked for a few minutes.
But there might be better solutions.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: One copy of the program?

Post by Foz »

The open network port method is what we use at work.

- we've had cases where the global mutexes sometimes didn't work (still don't know why and after spending 2 days on it, time was devoted to finding a better cure)

- using a locking file, though clean in theory forgets about the fact that programs can crash for a multitude of reasons, and then locks the users out

- using a lock via a database, again clean, but will require help desk support for when they are crashed out. (We do use this one at work coupled with proactive error reporting, but meaningful error reporting only available to us with .net)

- We acknowledge that using the network ports can be risky (as in another program that ISN'T yours is will be listening on a port above 50,000, but at the same time, it is highly unlikely, and in a business environment, we can ensure that if something IS, then it needs to be removed from that machine. If you want to go this route and it's for anyone and everyone to use, use a settings page to "generate" a secure port (basically, try to open a port, if it fails, increment 1, etc), and then use those settings every time.

- Another method would be to use the network port and locking file together - if both are set, then you know your program is running, if the port is free, but the locking file exists, then you simply crashed out, if the network port is blocked but there is no locking file, then another program is using that port (bring up the settings), and if neither are set, then you are free to carry on.
lakomet
User
User
Posts: 53
Joined: Mon Apr 04, 2011 3:56 am
Location: Russia,Angarsk

Re: One copy of the program?

Post by lakomet »

Foz
thank you
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
Ramihyn_
Enthusiast
Enthusiast
Posts: 314
Joined: Fri Feb 24, 2006 9:40 am

Re: One copy of the program?

Post by Ramihyn_ »

I have first used a seperate thread with an application specific file in the global temp directory. The seperate thread writes a timestamp every 5 seconds, so if the file exists, you can read the timestamp and check if it is "outdated" (older then 11 seconds in my case). If it is outdated, you can just silently erase the tempfile and create your own. Otherwise a "the application seems in use" requester is opened with directions how to recover if this would be an error. We used to record the User + Machine into the file additionally, so we could show those info's in these rare cases of crash recovery.

The second method i used, was a base network port number and a seperate thread which communicates with other instances of the application. If the base port (for example 50000) is used, the new instance connects to the port and does an application specific handshake. For example saying "hi i am Ramihyns app V 0.25, who are you?" and my own app would reply "hey cool, i am Ramihyns app V 0.5". If the service doesnt correctly reply to the communication, there is a predetermined offset we use, for example 1000. So we do the same on port 51000 and we have a limit of 10 attempts. So the app tries 50000, 51000, 52000 till 60000. That method works well in the field, can recover from crashes (remember that ports can be in use for up to some minutes after your application crashed) and the protocol has grown a lot to include license managing, data exchange and other usefull stuff.

A major downside of the network based method, is that some virus scanners can act "funny" if you do it. Some interfere and ask the user who then will wonder why your software is trying to connect to the "internet" or even worse "starts a network service". That can result in support requests from paranoid users. Thats why we use global mutexes for our windows versions, because it regularly gave us trouble in windows. I guess another downside might be that you unintentionally crash some other network service if it cant deal with your "hello" message. It never happened to me, but you could just change it so the client doesnt say anything and waits 3 seconds for your app to send its "Hi i am ..." string and if nothing happens, just assumes that it is some other app and closes the port again.

In practise dont use something like 50000 with steps of 1000, but better like 48627 and steps of 692. Numbers that another developer is unlikely to choose "randomly" ;)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Re: One copy of the program?

Post by remi_meier »

Ramihyn_ wrote:[...] The seperate thread writes a timestamp every 5 seconds, so if the file exists, you can read the timestamp and check if it is "outdated" (older then 11 seconds in my case). [...]
Short remark: Doing it like that usually prevents my
laptop hard drive from going to sleep. I would therefore
advise against anyone using that kind of method for
long-running applications.
Athlon64 3700+, 1024MB Ram, Radeon X1600
lakomet
User
User
Posts: 53
Joined: Mon Apr 04, 2011 3:56 am
Location: Russia,Angarsk

Re: One copy of the program?

Post by lakomet »

That's what I got

Code: Select all

Procedure get_running_programm(prog.s)
     Protected RegEx.i = CreateRegularExpression(#PB_Any, "[0-9]")
     Protected Directory.s = "/proc"
     Protected ExamDir.i = ExamineDirectory(#PB_Any, Directory, "*.*") 
     Protected OutFile.i
     If RegEx And ExamDir
          While NextDirectoryEntry(ExamDir)
               If MatchRegularExpression(RegEx, DirectoryEntryName(ExamDir))
                    OutFile = ReadFile(#PB_Any,Directory+"/"+DirectoryEntryName(ExamDir)+"/stat")
                    If  OutFile
                         If FindString(ReadString(OutFile), prog, 1)
                              CloseFile(OutFile)
                              ProcedureReturn 1
                         EndIf 
                         CloseFile(OutFile)
                    EndIf 
               EndIf
          Wend
          FinishDirectory(ExamDir)
     EndIf
     ProcedureReturn 0
EndProcedure

Debug get_running_programm("purebasic")
Debug get_running_programm("pure-basic")
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Re: One copy of the program?

Post by akj »

Here are other ways to prevent running multiple copies of a program:

http://www.purebasic.fr/english/viewtop ... 12&t=33129
Anthony Jordan
Post Reply