寒星轩

There are innumerable stars in the sky, the smallest is me!

李星ID:starlee
198712次访问,排名343(1)好友0人,关注者55
欢迎大家访问我的Blog。
主要是C++,设计模式,面向对象设计方面的技术文章。
starlee的文章
原创 94 篇
翻译 0 篇
转载 45 篇
评论 300 篇
StarLee的公告
郑重声明

        本BLOG所发表的 原创文章,作者保留一切权利。必须经过作者本人同意后方可转载,并注名作者(StarLee)和出处(CSDN Blog)。
作者Email:
coolstarlee(at)sohu.com
最近评论
lizhenneng:很有意思的程序。作者写出来是为了让别人分享自己的知识,却有人在那里泼凉水,真替那些人悲哀。
neng:程序还蛮有意思的,谢谢些出来分享,那些说恶话的请闭上你们的嘴巴吧,作者写出来是想让大家分享他的知识,你们却在那里泼凉水,无语.
zigzag5:这个思路好像在《COM本质论》中间过,不错。

还有那些恶评作者的,省省吧,人家写了不是一定要你看的。有营养你就吸收,没有营养你就略过好了。就算你知道的多一点,难道你不是从这个阶段过来的吗?
ztz0223:呵呵,上面争论挺激烈的啊,该不该用多继承是个人爱好,但是有很多优秀的类库都是使用了多继承的,比如,ATL,WTL,ACE等等,就连iostream这个类都是多继承的结果,难道他们用错了?
楼上的兄弟,还有c++ 0x出来能解决多继承的问题?现在的c++莫非就那么不上你的眼?
我跟楼主不认识,就事论事而已
dwc90715P32:顶!
文章分类
收藏
相册
友情链接
houdy的专栏
lijgame的专栏
lyrebing的专栏
禾青谷
存档
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 《程序只启动一个实例的几种方法》一文的补充收藏

新一篇: 又有一篇文章被推荐到CSDN首页 | 旧一篇: 文章同时登上CSDN Blog首页和CSDN首页

    我那篇《程序只启动一个实例的几种方法》发表后被推荐到了CSDN首页,有不少网友看了之后提出了一些很好的建议。其中有个网友说可以用共享变量法,我上网收集了一些资料,又经过代码测试,现在补充一下这种方法:
    五,共享变量法
    首先,在App类的cpp文件开头加上下面的代码:

#pragma data_seg("StarLee") // 自己定义的数据段
    
char nInstanceCount = -1// 实例个数,下文会详细用char来定义实例个数的好处
#pragma data_seg()
#pragma comment(linker, "/section:StarLee,rws") // 共享该数据段(r - read, w - write, s - share)

    然后,在App类的InitInstance()方法的最前面加上下面的代码:

nInstanceCount++;
if (nInstanceCount > 0)
{
    MessageBox(NULL, 
"该进程已经启动""错误", MB_OK);
        
    
return FALSE;
}

    最后,在App类的ExitInstance()方法里加上下面的代码:

nInstanceCount--;

    PS:这里介绍一下上面代码中用把实例个数的类型定义为char的小技巧。我们知道char的长度为1个字节,是用-128~127之间的整型来表示的。而我们进程实例的最大值是1,而且在程序的数据段里添加的东西越少越好,所以char就成了最佳之选。

    在那篇《程序只启动一个实例的几种方法》的十几个回复中,很多网友都提到了如果进程被意外终止,恢复设置的代码将不会被调用,那样程序就不能再被启动了。为此我针对每种方法都做了测试,下面对结果进行一下分析:
    测试环境:
    Windows 2000,VC++ 6.0
    测试方法:
    1,启动程序,在任务管理器终止该进程,再次启动进程。
    2,删除App类的ExitInstance()方法里面添加的代码,编译通过以后,启动程序,关闭程序,再次启动程序。
    结果:
    对于方法一和方法二(文件法和注册表法),由于有I/O操作,如果恢复设置的代码不被调用,除非手动将设置恢复,否则程序就永远不能再被启动。这也是我不推荐这两种方法的主要原因。
    对于后3种方法(文件映射法,互斥量法和共享变量法),就算进程被异常终止,恢复设置的代码不被调用,也不会影响程序的再次启动。我觉得,这是因为这3种使用的对象(文件映射,互斥量,共享变量)虽然可以夸进程访问,但是他们还是属于创建者进程的,会随着创建者的销毁而销毁,Windows会在进程结束(无论是正常还是意外)的时候释放它们。
    另外,我在MSDN对CreateMutex的介绍中发现了下面这句话:
    The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.
    可以说这是明确的告诉我们互斥量在程序终止的时候会被自动释放。
    所以,在我介绍的这些让进程只启动一个实例的五种方法中,互斥量法是最好的解决方法。

发表于 @ 2007年03月27日 09:21:00|评论(loading...)|编辑

新一篇: 又有一篇文章被推荐到CSDN首页 | 旧一篇: 文章同时登上CSDN Blog首页和CSDN首页

评论

#三点放松地方 发表于2007-03-28 12:22:27  IP: 10.193.44.*
互斥是最好的,我也是只用它
#captainwh 发表于2007-03-29 08:50:38  IP: 58.244.49.*
是啊互斥量的确是最好最简单的方法
#airby 发表于2007-03-29 13:44:10  IP: 218.19.65.*
使用CWinApp类中使用Singleton模式呀。那样就可以实现只有一个视例子。
#lijgame 发表于2007-04-21 21:38:27  IP: 218.1.229.*
用互斥确实是可行也最简单的。
但是也有,比如你的这个程序的一个实例被最小化到了系统托盘里,当用户启动另一个实例时,你希望把原先那个实例显示出来,这种情况下用枚举进程更好一点
#wky0711 发表于2007-08-07 16:24:20  IP: 218.104.96.*
从你的总结中受益不少
我有个问题请教一下
当进程A加载的Dll中创建了进程B,同一Dll在进程A需多次加载释放
如何实现进程B只被运行一次,且如何进程判断出运行则继续运行,没有运行则运行进程B
2007-08-08 11:15:59作者回复
其实你的问题并不难解决。可以分成3种情况来处理。(1)如果进程B也是你编写的,你就可以用我文章中的互斥量的方法来让进程B只启动一次,在DLL中通过创建同名的Mutex来判断进程B是否已经运行。(2)你不能在进程B中添加代码,但是却知道进程B什么时候终止,那么你可以在创建进程B的时候,同时创建一个Mutex,在进程B终止的时候销毁这个Mutex,同样通过创建同名的Mutex来判断进程B是否已经运行。(3)你不能在进程B中添加代码,而且不知道进程B什么时候终止,那么只有用枚举系统中所有进程来判断进程B是否已经启动了。
#wky0711 发表于2007-08-08 15:54:19  IP: 218.104.96.*
谢谢博主 回复已收到 我将按照你的方法试下
如果有不懂的可能还要请教你 希望你能有时间的话 指点一二 呵呵~~~
发表评论  


登录
Csdn Blog version 3.1a
Copyright © StarLee