One copy of the program?
One copy of the program?
Hi, how to prevent running multiple copies of the program?
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
Re: One copy of the program?
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/
Another idea:
http://www.linuxquestions.org/questions ... on-256693/
"Have you tried turning it off and on again ?"
Re: One copy of the program?
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.
If you fail to open the port, then your program is already running.
Re: One copy of the program?
You propose to use CreateNetworkServer (0, 50001)?Foz wrote:50000 as it's for temporary use
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
Re: One copy of the program?
Sounds like a big risk.Foz wrote:If you fail to open the port, then your program is already running.
If there's any other reason that makes it fail, your program won't run at all.
Re: One copy of the program?
There is a risk, but each program has a preference file, it can record you are currently using the port (0-65000)?wilbert wrote:Sounds like a big risk.
Linux Mint Maya(Mate), x86, PureBasic 5.00(5.10b1)
Re: One copy of the program?
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 ?"
Re: One copy of the program?
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.
Re: One copy of the program?
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.
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.
Re: One copy of the program?
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.
- 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.
Re: One copy of the program?
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"
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

- Posts: 468
- Joined: Sat Dec 20, 2003 6:19 pm
- Location: Switzerland
Re: One copy of the program?
Short remark: Doing it like that usually prevents myRamihyn_ 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). [...]
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
Re: One copy of the program?
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)
Re: One copy of the program?
Here are other ways to prevent running multiple copies of a program:
http://www.purebasic.fr/english/viewtop ... 12&t=33129
http://www.purebasic.fr/english/viewtop ... 12&t=33129
Anthony Jordan


