利用Mutex实现应用程序的单实例运行

System.Threading.Mutex :同步基元,它只向一个线程授予对共享资源的独占访问权。[MSDN]
实现原理: 在程序启动时,请求一个互斥体,如果能获取对指定互斥的访问权,就继续运行程序,否则就退出程序。
测试代码:

class Test

     {

         /// <summary>

         /// 应用程序的主入口点。

         /// </summary>

          [STAThread]

         static void Main(string[] args)

         {

              bool flag=false;

              System.Threading.Mutex mutex=new System.Threading.Mutex(true,"Test",out flag);

              //第一个参数:true--给调用线程赋予互斥体的初始所属权

              //第一个参数:互斥体的名称

              //第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true

              if(flag)

              {

                   Console.Write("Running");

              }

              else

              {

                   Console.Write("Another is Running");

                   System.Threading.Thread.Sleep(5000);//线程挂起5秒钟

                   Environment.Exit(1);//退出程序

              }

              Console.ReadLine();

         }


运行结果:
第一次运行,输出"Running"。
不关闭第一次运行的程序, 进行第二次运行,输出"Another is Running",五秒钟后,程序自动退出。
posted @ 2004-05-22 13:38 dudu 阅读(5248) 评论(13)  编辑 收藏 所属分类: C#

  回复  引用    
#1楼 2004-12-20 21:47 | stone [未注册用户]
按照你上面的说法,如果第一次运行,输出"Running"。
不关闭第一次运行的程序, 进行第二次运行,输出"Another is Running",当关闭第一个后再次运行第三个,第二个没有获得mutex的拥有权,是否应该显示running呢?

经过测试,依然显示Another is Running,这个怎么理解拥有权?
  回复  引用    
#2楼 2005-01-24 16:13 | pagechen_js@msn.com [未注册用户]
此时,第2个程序在运行,mutex对象依然存在。所以第3个事例运行时是修改互坼体所有权,而不是创建互斥体。显示结果证明了这一点。
我的理解是否正确?
  回复  引用    
#3楼 2005-03-09 17:14 | leppard [未注册用户]
少了个释放
ReleaseMutex();

  回复  引用  查看    
#4楼 [楼主]2005-03-09 19:15 | dudu      
@leppard
谢谢你的提示!
  回复  引用  查看    
#5楼 2005-03-28 15:52 | rottenapple      
我用类似的方法,发现在debug版本好用,在release版本不好用,不知道为什么阿?
  回复  引用    
#6楼 2005-07-21 08:33 | mKimTaeHee [未注册用户]
static void Main()
{

if (mSetFlag())
{
Application.Run(new Form1());
}
else
{
MessageBox.Show("该程序已经运行!!!");
// Application.Exit();

}

}


#region 检测程序是否已经运行
private static System.Threading.Mutex mMutex ;//静态变量属于类 ,非静态变量属于实例 .
private static bool mSetFlag()//静态方法属于类 ,非静态方法属于实例 .
{
bool bValue;
mMutex = new System.Threading.Mutex(true,"mKimTaeHee",out bValue);
return bValue;
}
#endregion


以上是本人写的,想问问 ReleaseMutex();
如何用
  回复  引用    
#7楼 2005-07-21 08:47 | mKimTaeHee [未注册用户]
by pagechen_js@msn.com
此时,第2个程序在运行,mutex对象依然存在。所以第3个事例运行时是修改互坼体所有权,而不是创建互斥体。显示结果证明了这一点。
我的理解是否正确?
======================
于是我开始理解:
当第1个程序在运行时,mutex对象存在。当第2个程序运行时是修改互斥体的所有权,而不是创建互斥体。(但是修改所有权,失败!未获得所有权)。
当第1个程序关闭后,mutex对象存在被回收。当第3个事例运行时你说他是修改互斥体所有权,还是创建互斥体呢? 汗 ~~我 理解能力差 大家别笑我,我是初级的 。希望高手能 解释清除 stone 的问题 ,谢谢。

  回复  引用    
#8楼 2005-07-22 11:04 | little [未注册用户]
当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

可以使用 WaitHandle.WaitOne 请求互斥体的所属权。拥有互斥体的线程可以在对 Wait 的重复调用中请求相同的互斥体而不会阻塞其执行。但线程必须调用 ReleaseMutex 方法同样多的次数以释放互斥体的所属权。如果线程在拥有互斥体期间正常终止,则互斥体状态设置为终止,并且下一个等待线程获得所属权。如果没有线程拥有互斥体,则互斥体状态为终止。

[以上内容摘自MSDN帮助]

我的理解:当程序第一次运行的时候,以“Test”为名称创建一个互斥体。互斥体相当于系统级别的对象,相同名称的只能有一个。所以,当程序第二次运行的时候,先检查是否存在此名称的互斥体,发现存在,于是就直接给其赋予所属权(true-第一个参数值),但此时不能成功。所以就返回false值(第三个参数)了。我们通过返回的值来确定程序是否已经运行了。 这里,我的理解是,程序第二次运行的时候,仅仅只是没有分配到所给定的权限,而所申请的互斥体已经得到了(和程序第一次运行时生成的互斥体是同一个),只是不能使用它而已。这样,当第一次运行的程序关闭以后,由于其生成的互斥体同时被第二次运行的程序所拥有,而不会清除掉。所以,程序第三次运行的时候,还是会检测到“Test”互斥体,而提示“程序已经运行”。

下面的代码:当第一次运行的关闭,而第二次运行的不关闭时,第三个运行时,是可以运行的。
static void Main()
{
bool blnOK;
Mutex m=new Mutex (true,"MyMutex",out blnOK);
if (blnOK)
{
Application.Run(new Form1());
//m.Close ();
}
else
{
m.Close ();
MessageBox .Show ("程序已经运行");
}

}
  回复  引用    
#9楼 2005-07-25 16:45 | mKimTaeHee [未注册用户]
明白了,谢谢。
//一种情况是,生成互斥体失败。返回false
//一种情况是,互斥体存在,而没有使用权限。返回false
  回复  引用    
#10楼 2005-08-25 15:39 | Mediar [未注册用户]
如果第一个已经运行,
再运行第二个时能否再做人判断

就是如果第一个程序窗体如果最小化,把把第一窗体最大化。第二个程序退出

  回复  引用    
#12楼 2006-03-22 18:28 | ljlllliiiihiohui [未注册用户]
bool isRun;
Mutex mu = new Mutex(true, "Applacationm1utes", out isRun);
if (!isRun)
{
MessageBox.Show("000000000000000");
return;

}
  回复  引用    
#13楼 2008-02-24 10:26 | xiaojiao [未注册用户]
--引用--------------------------------------------------
stone: 按照你上面的说法,如果第一次运行,输出&quot;Running&quot;。
不关闭第一次运行的程序, 进行第二次运行,输出&quot;Another is Running&quot;,当关闭第一个后再次运行第三个,第二个没有获得mutex的拥有权,是否应该显示running呢?

经过测试,依然显示Another is Running,这个怎么理解拥有权?
--------------------------------------------------------


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: