This prevents multiple copies of a program from running at the same time.
Programinstancemanagement. h
/** <Br/> * @ file programinstancemanagement. h <br/> * @ brief <br/> * @ author Hao liming <br/> * @ date 2009-5-7 13:32:35 <br/> * @ version <br/> * <PRE> <B> copyright: </B> </PRE> <br/> * <PRE> <B> Email: </B> hao.limin@gmail.com </PRE> <br/> * <PRE> <B> company: </B> http://blog.csdn.net/donhao </PRE> <br/> * <PRE> <B> All Rights Reserved. </B> </PRE> <br/> * <PRE> <B> modification: </B> </PRE> <br/> * <PRE> write modifications H Ere. </PRE> <br/> */</P> <p> # ifndef _ programinstancemanagement_h <br/> # DEFINE _ programinstancemanagement_h </P> <p> # ifdef Win32 <br/> # include <windows. h> <br/> # else <br/> # include <assert. h> <br/> # include <ctype. h> <br/> # include <errno. h> <br/> # include <limits. h> <br/> # include <string. h> <br/> # include <stdarg. h> <br/> # include <stdlib. h> <br/> # include <stdio. h> </P> <p> # include <syslog. h> <br/> # include <F Cntl. h> <br/> # include <sys/resource. h> <br/> # include <signal. h> <br/> # include <sys/STAT. h> <br/> # include <fcntl. h> </P> <p> # endif </P> <p> # include <string> </P> <p> class programinstancemanagement <br/> {<br/> public: </P> <p>/** <br/> * @ brief constructor for programinstancemanagement. <br/> * You can run only one instance program at the same time based on the uniqueness of name. <br/> * @ Param [in] Name defaults to "oneinsatnce ". <br/> */<br/> programinstancemanag Ement (STD: string name = "oneinsatnce"); </P> <p>/** <br/> * @ brief destructor for programinstancemanagement. <br/> */<br/> ~ Programinstancemanagement (); </P> <p>/** <br/> * @ brief isrunning <br/> * determine whether the program is running <br/> * @ return bool <br/> */<br/> bool isrunning (); </P> <p> protected: </P> <p> PRIVATE: <br/> # ifdef Win32 </P> <p>/** @ brief checks whether the program is running by using the Global mutex */<br/> STD :: string mutexname; <br/> # else <br/>/** <br/> * @ brief daemonize <br/> * @ Param [in] CMD <br/> */<br /> void daemonize (const char * cmd ); </P> <p>/** <br/> * @ brief lockfile <br/> * @ Param [in] FD <br/> * @ return int <br/> */<br/> int lockfile (int fd ); <br/> STD: String lockfile; <br/> # endif <br/>}; </P> <p> # endif // _ programinstancemanagement_h <br/>
Programinstancemanagement. cpp
/** <Br/> * @ file programinstancemanagement. h <br/> * @ brief <br/> * @ author Hao liming <br/> * @ date 2009-5-7 13:32:35 <br/> * @ version <br/> * <PRE> <B> copyright: </B> </PRE> <br/> * <PRE> <B> Email: </B> hao.limin@gmail.com </PRE> <br/> * <PRE> <B> company: </B> http://blog.csdn.net/donhao </PRE> <br/> * <PRE> <B> All Rights Reserved. </B> </PRE> <br/> * <PRE> <B> modification: </B> </PRE> <br/> * <PRE> write modifications H Ere. </PRE> <br/> */</P> <p> # include "programinstancemanagement. H "</P> <p> programinstancemanagement: programinstancemanagement (STD: string name) <br/> # ifdef <br/>: mutexname (name) <br/> # else <br/>: lockfile ("/tmp/" + name + ". PID ") <br/> # endif <br/>{</P> <p >}</P> <p> programinstancemanagement ::~ Programinstancemanagement () <br/>{</P> <p >}</P> <p> bool programinstancemanagement: isrunning () <br/>{< br/> # ifdef Win32 </P> <p> handle hmutexoneinstantance = createmutex (null, true, "ucclient "); <br/> bool bfound = false; <br/> If (getlasterror () = error_already_exists) <br/>{< br/> bfound = true; <br/>}< br/> If (hmutexoneinstantance) <br/>{< br/> releasemutex (hmutexoneinstantance); <br/>}< br/> If (bfound = True) <br/>{< br/> return true; <br/>}< br/> else <br/>{< br/> return false; <br/>}< br/> # else <br/> int FD; <br/> char Buf [16]; <br/> FD = open (lockfile. c_str (), o_rdwr | o_creat, s_irusr | s_iwusr | s_irgrp | s_iroth); <br/> If (FD <0) <br/>{< br/> return true; <br/>}< br/> If (lockfile (FD) <0) <br/>{< br/> If (errno = eacces | errno = eagain) <br/>{< br/> close (FD); <br/> return true; <br/>}< br/> return t Rue; <br/>}< br/> ftruncate (FD, 0); <br/> sprintf (BUF, "% lD", (long) getpid ()); <br/> write (FD, Buf, strlen (BUF) + 1); <br/> return false; <br/> # endif <br/>}</P> <p> # ifdef Win32 </P> <p> # else <br/> void programinstancemanagement :: daemonize (const char * cmd) <br/>{< br/> unsigned int I; <br/> int fd0; <br/> int fd1; <br/> int fd2; <br/> pid_t PID; <br/> struct rlimit RL; // maximum number of file descriptors saved <br/> struct sigaction SA; <br />/* <Br/> * clear file creation mask. the inherited mode may restrict some permissions <br/> */<br/> umask (0 ); </P> <p>/* <br/> * get maximum number of file descriptors. <br/> */<br/> If (getrlimit (rlimit_nofile, & RL) <0) <br/> perror (null ); </P> <p>/* <br/> after a sub-process is started, the parent process exits. Purpose: <br/> if the service is started by a shell command, so this operation will make the shell think that the command has been successfully executed, so that the terminal <br/> can ensure that the sub-process is not a leader process, this condition is the prerequisite for calling setsid <br/> */<br/> If (pid = fork () <0) <br/> perror (null ); <br/> else if (PID! = 0)/* parent */<br/> exit (0); </P> <p>/* <br/> after setsid is called: <br/> become the first process of a new session <br/> become the leader of a new process group <br/> no control terminal <br/> */<br/> setsid (); </P> <p>/* <br/> * ensure future opens won't allocate controlling TTYs. <br/> */<br/>/* <br/> ignore the signal disconnected from the control terminal <br/> */<br/> SA. sa_handler = sig_ign; <br/> sigemptyset (& SA. sa_mask); <br/> SA. sa_flags = 0; <br/> If (sigaction (sighup, & SA, null) <0) <br/> perror (null ); </P> <p>/* <br/> enable daemon The process is not the first process of the session, preventing it from obtaining Terminal Control <br/> */<br/> If (pid = fork () <0) <br/> perror (null); <br/> else if (PID! = 0)/* parent */<br/> exit (0); </P> <p>/* <br/> change the working directory, prevent uninstallation of the original working directory <br/> */<br/> If (chdir ("/") <0) <br/> perror (null ); </P> <p>/* <br/> * close all open files <br/> */<br/> If (RL. rlim_max = rlim_infinity) <br/> RL. rlim_max = 1024; <br/> for (I = 0; I <RL. rlim_max; I ++) <br/> close (I ); </P> <p>/* <br/> * directs the standard input output and standard error output to/dev/null. <br/> */<br/> fd0 = open ("/dev/null", o_rdwr); // because all files have been closed, therefore, the returned file descriptor must be 0 <br/> fd1 = DUP (0); // returns 1 for the same reason as above <br/> fd2 = DUP (0 ); // returns 2 <br/> sleep (8); <br/>}</P> <p> int programinstancemanagement: lockfile (int fd) for the same reason) <br/>{< br/> struct flock FL; </P> <p> FL. l_type = f_wrlck; // exclusive write lock <br/> FL. rochelle start = 0; // Rochelle start and Rochelle whence determine the start position of the lock. <br/> FL. rochelle whence = seek_set; <br/> FL. rochelle Len = 0; // The lock range. "0" indicates the end of the file <br/> return (fcntl (FD, f_setlk, & FL )); <br/>}</P> <p> # endif
Main. cpp
/** <Br/> * @ file programinstancemanagement. h <br/> * @ brief <br/> * @ author Hao liming <br/> * @ date 2009-5-7 13:32:35 <br/> * @ version <br/> * <PRE> <B> copyright: </B> </PRE> <br/> * <PRE> <B> Email: </B> hao.limin@gmail.com </PRE> <br/> * <PRE> <B> company: </B> http://blog.csdn.net/donhao </PRE> <br/> * <PRE> <B> All Rights Reserved. </B> </PRE> <br/> * <PRE> <B> modification: </B> </PRE> <br/> * <PRE> write modifications here. </PRE> <br/> */<br/> # include "programinstancemanagement. H "<br/> int main () <br/>{< br/> programinstancemanagement PM (" test "); <br/> If (PM. isrunning () <br/>{< br/> printf ("another program is running. this program will exit after 3 seconds. /n "); <br/> # ifdef Win32 <br/> sleep (3000); <br/> # else <br/> usleep (3000000 ); <br/> # endif <br/> return 0; <br/>}< br/> else <br/>{< br/> # ifdef Win32 <br/> sleep (3000 ); <br/> # else <br/> usleep (3000000); <br/> # endif <br/>}< br/> return 0; <br/>}</P> <p>