To redbb(....Dotneter....):   不是已经加了mutex锁了?

解决方案 »

  1.   

    private static Mutex rc = new Mutex();
    private static Mutex wsem = new Mutex();用一下其他构造函数呢?
      

  2.   

    To idiotzeng(白痴):
       试了一下其他构造函数。no effect。To mobydick(敌伯威):
       刚才试了一下lcok。问题和原先一模一样。To bitsbird(一瓢.net):
      “mscorlib.dll 有问题”:有什么问题呢?
      

  3.   

    你这样写只能保证多个线程读的时候只有一个线程读文件和多个线程写的时候只有一个线程写文件啊!
    应该用同一个Mutex在读和写的线程中!
      

  4.   

    to 楼主:
      如果mutex不行的话,建议尝试下Monitor的静态方法Enter()和Exit()结合静态方法Wait()
    和Pulse()一样可以实现
    比如说:
    using System.Threading;
    ...
    public class Test{
       ...
       private int i=1;
       public void Circle(){
           Monitor.Enter(this.i); //同步锁住这段代码区
           for(int i=0;i<10;i++){
                Monitor.Wait(this.i);
                Console.Write("Circle has been woken up!");
                Monitor.Pulse(this.i);
               }
           Monitor.Exit(this.i);
           }
       public void noCircle(){
           Monitor.Enter(this.i)
           for(int i=0;i<10;i++){
                Monitor.Pulse(this.i);  //唤醒
                Console.Write("noCircle is running");
                Monitor.Wait(this.i);   //等待
                Monitor.Pulse(this.i);
                Console.Write("noCircle has been woken up!");
              } 
            Monitor.Exit(this.i);
          }
          ...
    }
    运行结果是:
     noCircle is running
     Circle has been woken up!
    noCircle has been woken up!
      ...注意:wait()和pulse()只能用在Enter()和Exit()锁定的代码中!
    这样实现的功能就是操作系统中的原语p,v操作                                                       wish u good luck
                                                               Greatsft
      

  5.   

    刚才使用Monitor试了一下,输出的读写流程不正确。
    看了一本SDK的书,说Win32的Mutex不能用来锁定这里的wsem。这和.NET有什么关联没有?
      

  6.   

    你要实现什么?Monitor的wait()和pulse()就是实现原语p,v操作的
      

  7.   

    to greatsft(C的使者):
      
    thanks。
    Monitor相当于CriticalSection?
    如何在C#中实现象MFC中的EnterCriticalSection、LeaveCriticalSection的功能?
    我需要的正是这个。
      

  8.   

    Monitor.Wait、Monitor.Pulse和P、V原语好象是不同的。
    Wait()直接就把线程移到等待队列了,而P原语有一个判断。
      

  9.   

    当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。你用了两个互斥体能不出错吗!?
    “调用线程不拥有互斥体”异常也是正确的,你没有调用互斥体的WaitOne方法就调用ReleaseMutex方法就是这个结果啊!
      

  10.   

    to liu_z_j():
       
       你说的对。Mutex有个所有权问题,只有拥有者才能释放,所以我的代码出错。
       我正在尝试用Monitor...
      

  11.   

    to redbb:
      
       ReaderWriterLock能实现互斥,但是可控性太差。
       无法实现读/写者优先的要求。谁能介绍一下如何用Monitor替代MFC中的EnterCriticalSection和LeaveCriticalSection。
    我用Monitor.Enter和Monitor.Exit程序运行时死锁。
      

  12.   

    to ejiue(猪慕狼犸)
         的确象你说的p,v操作是有一个判断,但是我的意思是在c#中调用wait()和pulse()
    要实现的功能就是和操作系统中用p,v来互斥操作一样to 楼主
         你说的mfc中的两个方法我没用过,不过你可以说说你想实现的具体功能,不过
    按照你上面的描述,我说的方法肯定行
      

  13.   

    无论是Monitor也好,Mutex也好,都要求同一线程执行Enter、Exit或Wait、Release。
    我现在需要象EnterCriticalSection、LeaveCriticalSection那样的,不需要由同一个
    线程执行,并且当某个线程LeaveCriticalSection以后,阻塞在EnterCriticalSection
    上的线程能马上得到通知的机制。Monitor的Wait、Pulse又必须写在Enter、Exit内,而且语义和P、V原语不大一致。
    想不懂.net为什么不沿用原来的机制。
      

  14.   

    查了一下Modern Operating System,原来Monitor是“管程”的意思。
    由于管程比信号量高级,所有C#没有提供专门的信号量。
    根据管程的定义和原语等价,我自己写了一个Semaphore类。using System;
    using System.Threading;namespace Reader_Writer
    {
        /// <summary>
        /// Semaphore。
        /// </summary>
        public class Semaphore
        {
    private object mx;
    private int counter;

             public Semaphore()
    {
       counter = 1;
       mx = new object();
    } public void Down()
    {
       Monitor.Enter(mx);
       counter--;
       if ( counter < 0 )
       {
           Monitor.Wait(mx);
       }
       Monitor.Exit(mx);
    }
    public void Up()
    {
       Monitor.Enter(mx);
       counter++;
       if ( counter <= 0 )
       {
           Monitor.Pulse(mx);
       }
       Monitor.Exit(mx);
             }
        }
    }正确的读者-写者实现:
    private static Semaphore rsem = new Semaphore();
    private static Semaphore wsem = new Semaphore();
    private static int readercount = 0; private static void ReaderThreadProc_ReaderPriority()
    {
        string threadname = Thread.CurrentThread.Name;
        int id = int.Parse(threadname);
        int delay = Convert.ToInt32(GetThreadDelay(id)*1000);
        int persist = Convert.ToInt32(GetThreadPersist(id)*1000);    Thread.Sleep(delay); 
        Console.WriteLine("{0} is requesting for reading",threadname);      rc.WaitOne();
        readercount++;
        if ( readercount == 1 )
        {
    wsem.Down();
        }
        rc.ReleaseMutex();    Console.WriteLine("{0} is beginning reading",threadname);
        Thread.Sleep(persist);
        Console.WriteLine("{0} is ending reading",threadname);     rc.WaitOne();
        readercount--;
        if ( readercount == 0 )
        {
           wsem.Up();
        }
        rc.ReleaseMutex();
    }private static void WriterThreadProc_ReaderPriority()
    {
        Thread.Sleep(delay);
        Console.WriteLine("{0} is requesting for writing",threadname);    wsem.Down();
        Console.WriteLine("{0} is beginning writing",threadname);
        Thread.Sleep(persist);
        Console.WriteLine("{0} is ending writing",threadname);
        wsem.Up();
    }小结:
        1、Mutex由于存在所有权的问题,必须由所有者释放,这和P、V原语是不能等同的。
           在实际使用时要小心。
        2、用ReaderWriterLock实现读者-写者比较简单,但是只能实现互斥,
           不能实现读者优先或写者优先的特殊要求,因此灵活性较差。
        3、Monitor,即管程,是比较高级的概念。但是和P、V原语是可以等价的。
           我用它来实现了信号量(Semaphore),并成功的解决了读者-写者问题。
        4、Semaphore,信号量,C#没有直接提供,但可以用Monitor实现。
           相当于MFC里的CriticalSection。非常好用。
           
      

  15.   

    这几天为了解决这个问题,查了很多方面的资料。
    MSDN、Google上都没有找到Monitor实现Semaphore的相关说明。
    希望这个帖子能给和我一样遇到这个问题的朋友一点帮助。
     
    谢谢大家,揭贴。