专栏首页闷骚的程序员Windows 实现单实例进程的两种方法

Windows 实现单实例进程的两种方法

方法一:共享静态数据。

此方法参见《Windows 核心编程》第 5 版 17.1.2 章节《在同一个可执行文件或 DLL 的多个实例间共享静态数据》。

实现原理:

创建一个自己命名的段,将其属性改为 READ|WRITE|SHARED,其中 SHARED 属性表示该段的内容为多个实例所共享(实际上关闭了写时复制机制),将变量放在该段内若值被改变,多个实例间都会受到改变的影响。

注意点:

  • 最好使用 volatile 修饰变量。
  • 对变量的增减推荐使用原子操作函数 InterlockedExchangedAdd。
  • g_lInstances 的值在第一个实例运行时总为 0,其它实例中取到的值以先于它运行的实例中改变后的值为准。

示例代码:

#include <Windows.h>

#pragma data_seg("Shared")
volatile long g_lInstances = 0;
#pragma data_seg()

#pragma comment(linker, "/Section:Shared,RWS")

int main(int argc, char *argv[])
{
    if (g_lInstances != 0)
    {
        return -1;
    }

    InterlockedExchangeAdd(&g_lInstances, 1);

    // do something here
    // ...

    InterlockedExchangeAdd(&g_lInstances, -1);

    return 0;
}

方法二:使用 Mutex。

理论上能用于进程间同步的内核对象比如事件和互斥量等都能用于实现此功能,此处使用互斥量 Mutex 举例。

实现原理:

使用操作系统范围内可见的命名内核对象,不同实例间检测同一个内核对象的状态来判断是否为当前唯一实例。

注意点:

  • 内核对象要使用全局命名,比如此处使用 Global 开头。

示例代码:

#include <Windows.h>

int main(int argc, char *argv[])
{
    HANDLE hMutex = NULL;

    do
    {
        hMutex = CreateMutex(NULL, FALSE, "Global\\73E21C80-1960-472F-BF0B-3EE7CC7AF17E");

        DWORD dwError = GetLastError();

        if (ERROR_ALREADY_EXISTS == dwError || ERROR_ACCESS_DENIED == dwError)
        {
            break;
        }

        // do something here
        // ...

    } while (false);

    if (NULL != hMutex)
    {
        CloseHandle(hMutex);
    }

    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 更聪明地学习,而不是苦读——《如何高效学习》

    所以,需要持续大量学习的童鞋,比方说我等程序员们,除了要从知识的海洋中精挑细选出我们想要的内容,挑完了还得高效学习,不然成长的速度可能远远赶不上脱发的速度,沦落...

    mzlogin
  • 如何让 HelloWorld.apk 体积最小

    按照最新 ADT 的默认设置(如下图所示)创建一个最简单的 HelloWorld 程序,会发现最后生成的 apk 文件大小就已经达到了惊人的 903KB。如果只...

    mzlogin
  • TortoiseSVN 从 GitHub 更新时发生异常

    使用 TortoiseSVN 从 GitHub 仓库 Update 时,弹出错误提示对话框:

    mzlogin
  • 栈的基本操作就是出栈和入栈,这两个的时间复杂度都是O(1) 数据结构 typedef struct Stack{ int data[MAXSIZE]; ...

    用户1154259
  • Java 最常见的 208 道面试题:第九模块和第十模块答案

    这个模式本身很简单而且使用在业务较简单的情况下。一般用于小项目或者具体产品很少扩展的情况(这样工厂类才不用经常更改)。

    Java团长
  • Python的类和对象

    对象=属性(特征)+方法(行为) 类:在python中,把具有相同属性和方法的对象归为一个类(class) self: init()构造方法,只要实例化一个对象...

    企鹅号小编
  • SysML 2019论文解读:视频分析系统的提升

    系统与机器学习会议(SysML)是一个非常新的会议(始于 2018 年),针对的是系统与机器学习的交叉领域。该会议的目标是引出这些领域之间的新联系,包括确定学习...

    机器之心
  • 聊聊artemis的MessageLoadBalancingType

    activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis...

    codecraft
  • 从头到尾解析Hash 表算法

    问题描述 百度面试题: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。 假设目前有一千万个记...

    后端技术探索
  • 06:图像相似度

    06:图像相似度 总时间限制: 1000ms 内存限制: 65536kB描述 给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度。 说明:若两幅图...

    attack

扫码关注云+社区

领取腾讯云代金券