LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-17-2015, 11:02 AM   #1
zexen
LQ Newbie
 
Registered: Aug 2015
Posts: 2

Rep: Reputation: Disabled
Exclusive running processes for linux


I want ensure the application is not launched twice on the same computer but I failed.

My task is to port our application from Windows to UNIX-like systems. At least to Alt-Linux (uname -srvoi shows:
Linux 2.6.32-el-smp-alt27 #1 SMP Tue Sep 20 19:35:51 UTC 2011 unknown GNU/Linux). I'am not familiar with Linux-es before, hence send my question to this sub-forum for noobs.

For Windows I just create file in write mode and with ban for writing for other applications. On application exit I close the file and delete it. If application crushed or forcibly terminated it is OK because file stay existing but system allows to me to create it again.

For Alt-Linux I already tried:

1) 'fopen' file and 'lockf' it
- result: F_TEST hangs second instance of application instead immediately return with error. Probably it is beacuse file system is nfs and cannot lock files. (No, I cannot select other file system. App should work on nfs too.)

2) 'fopen' file and 'flock' it
- result: the same

3) 'open' file with O_CREATE|O_EXCL flags (mode is 0666)
- result: OK until I forcibly terminates first instance. As result file stay on disk and I cannot start application again

4) 'unlink' file and immediately 'open' it with O_CREATE|O_EXCL
- result: just does not work. I can start second instance (yes, I know in UNIX 'unlink' removes file only from directory but keep on disk until first instance closed file handle)

5) Use 'shm_open' with O_CREATE|O_EXCL flags
- result: as in 3)

6) Use 'shm_unlink' + 'shm_open' with O_CREATE|O_EXCL flags
- result: as in 4)

7), 8) Use 'sem_open' with O_CREATE|O_EXCL flags with or without sem_unlink before
- result: as in 3), 4)

10) Use 'sem_open' with O_CREATE, without O_EXCL but use 'sem_trywait' after
- result: OK until I forcibly terminates first instance. As result semaphore stay with value 0 and application cannot start again. I can delete semaphore but I do not know how to distinguish situations:
- semaphore is 0 because application is already running
- semaphore is 0 because application crushed

Below sample code:
Code:
int main()
{
  sem_t *sem= sem_open("/a.out.sem", O_CREAT, 0666, 1);
  if (sem != SEM_FAILED)
  {
      printf("success\n");
      if (0 == sem_trywait(sem))
          printf("trywait ok\n");
      else
          printf("cannot trywait\n");
  }
  else
      printf("failure\n");
  for(;;)
  {
      sleep(1);
  }
  return 0;
}
Start application and abort it with ^C to imit situation of application is killed before can call sem_post and/or sem_unlink.

What can I do?
 
Old 08-17-2015, 07:04 PM   #2
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
What are you trying to accomplish by only allowing sequential runs?

If you are attempting a licensing limit, this is not the way to go.

Last edited by jpollard; 08-17-2015 at 07:06 PM.
 
Old 08-17-2015, 07:28 PM   #3
zexen
LQ Newbie
 
Registered: Aug 2015
Posts: 2

Original Poster
Rep: Reputation: Disabled
Simultaneous execution just has not sense for some our applications, may confuse user or interfere each other. For example one of our apps retrieves records from database, processing them and delete them as 3 separate actions with long inactivity period. Second such application give risk of rare "races", and do not give any benefits. It's possible to use some additional checks and/or inter-process mutexes during DB processing but more effective way is make single check on attempt to start second instance.

Similar situation for other app: heavy and complex GUI already have multi-window design and second such GUI give nothing to user and will cause conflicts with status files. Probably second instance will result of superfluous click on start button etc so better show error to user immediately instead long loading screen and errors later/

Third application will fail on attempt start second instance because will try get the same TCP/IP port. But it is better to show user error more comprehensible message like "server is already started" instead "cannot create socket".
 
Old 08-18-2015, 05:53 AM   #4
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Then your database needs transactions.

Actually, it sounds like you don't have a database at all, just a collection of files. With the complexity you indicate, you need a database server. That way the database itself can detect multiple user attempts, and reject them; as well as clean up from aborted connections.

And you can always translate "cannot create socket" into a comprehensible message.

The only way you can control such access is by a "server process" than manages a semaphore. And using a socket connection allows the "server process" to detect aborted connections and perform the free operation. Using a real database would be both more efficient (it separates the data handling from the user interface), but faster too.
 
Old 08-18-2015, 06:07 AM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,838

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
the "usual" way is to use pid files:
when you start your application it will check if pidfile exists. If not - ok. If it was found check the content (that is a pid, and need to check if that pid belongs to a valid process or not).
 
Old 08-18-2015, 07:08 AM   #6
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by pan64 View Post
the "usual" way is to use pid files:
when you start your application it will check if pidfile exists. If not - ok. If it was found check the content (that is a pid, and need to check if that pid belongs to a valid process or not).
The problem with pid checking is that a pid can be reused...
 
Old 08-18-2015, 07:38 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,838

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
yes, that's why you need to check both the pid and the process name belongs to that pid (and obviously if that pid is still valid or not).
 
Old 08-18-2015, 10:00 AM   #8
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by pan64 View Post
the "usual" way is to use pid files:
when you start your application it will check if pidfile exists. If not - ok. If it was found check the content (that is a pid, and need to check if that pid belongs to a valid process or not).
This is typically what I do as well.

Dump the pid to a file, clean it up when you're done. When you first launch see if the pid file already exists, if it does read the pid out of it, then check the process associated with that pid to verify it's both still running and is associated with the process name you expect, then either kill it or kill yourself, depending on the behavior you want.
 
Old 08-18-2015, 04:18 PM   #9
sgrlscz
Member
 
Registered: Aug 2008
Posts: 123

Rep: Reputation: 84
I usually use a variation of the following:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <errno.h>

main() {
  int lock_file = open("/tmp/singleinst.lck", O_CREAT | O_RDWR, 0666);
  if (lock_file != -1) {
    int lock = flock(lock_file, LOCK_EX | LOCK_NB);
    if (lock) {
      if (errno == EWOULDBLOCK) {
	printf("another instance is running\n");
	exit(0); 
      }
    } 
  } else {
    perror("open failed");
  }

  // main loop
  // cleanup
}
The first process can open/create the file and lock it. As the long the file remains open and locked, any other process that starts will fail immediately trying to get the lock. If the process dies before the file is cleaned up, the file will be left around but the lock will be released, so it won't block starting a new process.

If it's daemon, then I usually use the pidfile as the lock file (i.e., open/create, lock it, write the pid, then leave it open and locked).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Help Me find and kill non local processes running for over 3 days on linux sudheergodgeri Linux - Newbie 1 05-13-2014 10:58 AM
How to schedule multiple infinitely running processes in linux, in C ShankyV Programming 3 04-16-2013 06:24 AM
are all processes running in linux required shyam_d_sundar Linux - Newbie 3 03-08-2004 01:03 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration