单实例应用程序

一、概念:一个程序在系统中只能启动一个实例,这样的程序称为单实例应用程序。例如Windows下的任务管理器、回收站、播放器、文件系统等等。

二、实现思想与方法:

(1)核心思想:在当前系统中,只需要有能表示程序是否启动的标志,那么就可以利用它来实现单实例应用程序。

(2)具体步骤:每当程序启动的时候,都需要先检测这个启动标志,当标志指示已经有实例存在,则当前程序退出,否则运行业务。

(3)实现单实例应用程序的方法:共享内存、绑定端口、命名管道、文件锁等等。

三、实现案例:运用文件锁实现

代码转载:http://www.cnblogs.com/highway-9/p/5517990.html

  1 /************************************************
  2 * 该例程讲解Linux下程序只运行一个实例的编程实现
  3 *
  4 * 编写只运行一个实例的程序有很多种方式,比如通过管道
  5 * 共享内存、文件锁等,主要是要有一个全局flag标志该程序
  6 * 已经在运行了,本程序使用文件锁来实现单实例
  7 ************************************************/
  8 #include <unistd.h>
  9 #include <fcntl.h>
 10 #include <sys/stat.h>
 11 #include <sys/types.h>
 12 #include <errno.h>
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15 #include <string.h>
 16 #include <string>
 17
 18 #ifndef PATH_MAX
 19 #define PATH_MAX 1024   // 默认最大路径长度
 20 #endif
 21
 22 std::string currentExeName()
 23 {
 24     char buf[PATH_MAX] = { ‘\0‘ };
 25
 26     int ret = readlink("/proc/self/exe", buf, PATH_MAX);
 27     if (ret < 0 || ret >= PATH_MAX)
 28     {
 29         return "";
 30     }
 31
 32     std::string path(buf);
 33     int pos = path.find_last_of("/");
 34     if (pos == -1)
 35     {
 36         return "";
 37     }
 38
 39     path = path.substr(pos + 1, path.size() - 1);
 40
 41     return path;
 42 }
 43
 44 bool runSingleInstance()
 45 {
 46     // 获取当前可执行文件名
 47     std::string processName = currentExeName();
 48     if (processName.empty())
 49     {
 50         exit(1);
 51     }
 52
 53     // 打开或创建一个文件
 54     std::string filePath = std::string("/var/run/") + processName + ".pid";
 55     int fd = open(filePath.c_str(), O_RDWR | O_CREAT, 0666);
 56     if (fd < 0)
 57     {
 58         printf("Open file failed, error : %s", strerror(errno));
 59         exit(1);
 60     }
 61
 62     // 将该文件锁定
 63     // 锁定后的文件将不能够再次锁定
 64     struct flock fl;
 65     fl.l_type = F_WRLCK; // 写文件锁定
 66     fl.l_start = 0;
 67     fl.l_whence = SEEK_SET;
 68     fl.l_len = 0;
 69     int ret = fcntl(fd, F_SETLK, &fl);
 70     if (ret < 0)
 71     {
 72         if (errno == EACCES || errno == EAGAIN)
 73         {
 74             printf("%s already locked, error: %s\n", filePath.c_str(), strerror(errno));
 75             close(fd);
 76             return false;
 77         }
 78     }
 79
 80     // 锁定文件后,将该进程的pid写入文件
 81     char buf[16] = { ‘\0‘ };
 82     sprintf(buf, "%d", getpid());
 83     ftruncate(fd, 0);
 84     ret = write(fd, buf, strlen(buf));
 85     if (ret < 0)
 86     {
 87         printf("Write file failed, file: %s, error: %s\n", filePath.c_str(), strerror(errno));
 88         close(fd);
 89         exit(1);
 90     }
 91
 92     // 函数返回时不需要调用close(fd)
 93     // 不然文件锁将失效
 94     // 程序退出后kernel会自动close
 95     return true;
 96 }
 97
 98 int main()
 99 {
100     if (!runSingleInstance())
101     {
102         printf("Process is already running\n");
103         return 1;
104     }
105
106     printf("Process start...\n");
107     sleep(5);
108     printf("Process end...\n");
109
110     return 0;
111 }
时间: 2024-07-29 09:05:32

单实例应用程序的相关文章

使用 WPF 创建单实例应用程序

一个简单的例子就是大家在使用很多应用程序,例如在使用Microsoft Word 时会遇到一种情况,不管你打开多少个文档,系统一次只能加载一个winword.exe 实例.当打开新文档时,文档在新窗口显示,但是始终只有一个应用程序控制所有文档窗口:如:可以提供平铺当前所有文档中相邻窗口的文档的特性. 对于创建单实例的应用程序,WPF本身没有提供自带的解决方法,但可以通过变通的方式来实现——思路是当触发ApplicationStartup事件时,检查另一个实例是否在运行.方法是通过使用全局的mut

WPF学习笔记 - 如何用WPF创建单实例应用程序

使用一个已命名的(操作系统范围的)互斥量. bool mutexIsNew; using(System.Threading.Mutex m = new System.Threading.Mulex(true, uniqueName, out mutexIsNew)) { if(mutexIsNew) { //This is the first instance, can run the appliacation } else { //There is an instance running, e

c#设计应用程序单实例运行

利用WindowsFormsApplicationBase的IsSingleInstance来控制应用程序只能单实例运行. [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("User32.dll"

WPF:如何实现单实例的应用程序(Single Instance)

原文:WPF:如何实现单实例的应用程序(Single Instance) 好吧,这是我将WPF与Windows Forms进行比较的系列文章的第四篇,讨论一下如何实现单实例(single instance) 先来看第一种最简单粗暴的做法: 检测进程名,如果名称一样,则表示程序已经启动了,就不再启动. protected override void OnStartup(StartupEventArgs e) { // Get Reference to the current Process Pro

C++实现程序单实例运行的两种方式

简介 在我们编写程序的时候,经常会注意到的一个问题就是如何能够让程序只运行一个实例,确保不会让同一个程序多次运行,从而产生诸多相同进程,给我们的带来不便呢?那么常用的有以下四种方法,第一种方法是通过扫描进程列表比对进程名来检测,第二种方法是通过枚举程序窗口的方式,第三种方法是采用共享全局变量来实现,第四种方法是通过创建互斥体来实现. 那么在这些方法中,第一种和第二种方法是有缺陷的,扫描进程列表比对进程名容易对相同进程名字的不同程序产生误报,枚举窗口不适用于无窗口程序且与扫描进程列表的方法也有相同

Spring单实例、多线程安全、事务解析

原文:http://blog.csdn.net/c289054531/article/details/9196053 引言: 在使用Spring时,很多人可能对Spring中为什么DAO和Service对象采用单实例方式很迷惑,这些读者是这么认为的: DAO对象必须包含一个数据库的连接Connection,而这个Connection不是线程安全的,所以每个DAO都要包含一个不同的Connection对象实例,这样一来DAO对象就不能是单实例的了. 上述观点对了一半.对的是“每个DAO都要包含一个

【单实例】php

从以上代码中,我们总结出PHP单例模式实现的核心要点有如下三条:1.需要一个保存类的唯一实例的静态成员变量(通常为$_instance私有变量)2.构造函数和克隆函数必须声明为私有的,这是为了防止外部程序new类从而失去单例模式的意义3.必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用PHP单例模式的缺点众所周知,PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收.也就是说,PHP在语言级

MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误

今天照着孙鑫老师的VC++教程学习文件的操作,VS2010,单文档应用程序,项目文件命名为File,也就有了自动生成的CFileDoc.CFileView等类,一进去就编译运行(就是最初自动生成的项目),编译通过,可运行时直接弹出错误框,有点小懵,,,啥都没做就给我看这个: 图一   错误提示框 后来搜索一查,网上好多类似的错误以及解决方案,几乎都试了个遍,有: 方法(1)-重新生成解决方案,或者将项目文件目录下Debug文件夹删了,重新生成Release版: 方法(2)-可以先声明一个临时的C

关于struts和Spring 结合到一起之后存在ACtion创建单实例还是多

转自(http://www.cnblogs.com/zyzcj/p/5652128.html) struts 2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象.原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面.如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了.所以Struts2的Action是多例模式的. 问题出现了,可以让struts2的action变成单