WINDOWS
" 进程互斥 "这个词可能有点陌生,所WINDOWS谓的 进程互斥 ;就是在一台终端上只能运行一个实例。如果当前程序已经在终端上运行,那么当你在次运行这个程序时,程序就会检测到当前程序已经运行,那么当前就会结束自身不在运行。
//使用CreateMutex函数来判断
//功能:确保程序只有唯一的实例
//返回值:0-正常;1-已经有一个正在运行的实例;-1 -创建互斥对象失败
int Program_Mutex()
{
HANDLE hMutex = NULL;
TCHAR * lpszName = L"APPMutex";
int nRet = 0;
do
{
hMutex = ::CreateMutex(NULL,FALSE,lpszName);
DWORD dwRet = ::GetLastError();
switch(dwRet)
{
case 0:
{
break;
}
case ERROR_ALREADY_EXISTS:
{
MessageBox(NULL,L"通知:该应用程序已经开启。\n",L"通知",MB_OK);
nRet = 1;
break;
}
default:
{
MessageBox(NULL,L"提示:该应用程序创建互斥对象失败。\n",L"错误",MB_OK);
nRet = -1;
break;
}
}
} while (FALSE);
return nRet;
}
LINUX
利用flock文件锁的方式来判断程序是否已启动,利用非阻塞的文件锁,对相应的文件进行上锁。成功获得文件锁的时候,就排斥了其它实例再次拿锁。在进程退出时,无论是正常退出还是意外崩溃的时候,Linux内核本身都会关闭该文件描述符。
表头文件 #include<sys/file.h>
定义函数 int flock(int fd,int operation);
参数 operation有下列四种情况:
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。
返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。
用法:flock只要在打开文件后,需要对文件读写之前flock一下就可以了,用完之后再flock一下,前面加锁,后面解锁。
进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误。
————————————————
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include<sys/file.h>
using namespace std;
static int g_single_proc_inst_lock_fd = -1;
static void single_proc_inst_lockfile_cleanup(void)
{
if (g_single_proc_inst_lock_fd != -1) {
close(g_single_proc_inst_lock_fd);
g_single_proc_inst_lock_fd = -1;
}
}
bool is_single_proc_inst_running(const char *process_name)
{
char lock_file[128];
snprintf(lock_file, sizeof(lock_file), "/data/app/.%s.lock", process_name);
g_single_proc_inst_lock_fd = open(lock_file, O_CREAT|O_RDWR, 0644);
if (-1 == g_single_proc_inst_lock_fd) {
fprintf(stderr, "Fail to open lock file(%s). Error: %s\n",
lock_file, strerror(errno));
return true;
}
if (0 == flock(g_single_proc_inst_lock_fd, LOCK_EX | LOCK_NB)) {
atexit(single_proc_inst_lockfile_cleanup);
return false;
}
close(g_single_proc_inst_lock_fd);
g_single_proc_inst_lock_fd = -1;
return true;
}
int main()
{
if(is_single_proc_inst_running("SCMIOT"))
{
printf("程序已运行!!!\r\n");
exit(1);
}
// system("pause");
sleep(30);
}