To redbb(....Dotneter....): 不是已经加了mutex锁了?
解决方案 »
- C#怎么实现点击文本框出现下拉菜单
- 问题的答案
- 求助!本地服务器的自动上传新的数据到远程服务器如何操作
- 如何实现:获取到经纬度,动态显示在地图对应的位置上
- 程序之间通讯问题
- 如何用C#向ACCESS数据库插入图片?
- scrollbar的问题
- 自定义控件怎么添加到form中
- 在线等,MSSQL数据库表的创建,增加字段,增加字段类型的C#原码!!
- 为什么我Asp.net运行后看不到dataGrid,而在查看源文件中有dataGrid的代码的,这是IE问题还是.net的问题?
- 请问哪位用OleDb打开dbf数据库查询数据成功过?
- 在winform中对datagrid里面值修改后怎样更新到数据库?(帮顶有分)
private static Mutex wsem = new Mutex();用一下其他构造函数呢?
试了一下其他构造函数。no effect。To mobydick(敌伯威):
刚才试了一下lcok。问题和原先一模一样。To bitsbird(一瓢.net):
“mscorlib.dll 有问题”:有什么问题呢?
应该用同一个Mutex在读和写的线程中!
如果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
看了一本SDK的书,说Win32的Mutex不能用来锁定这里的wsem。这和.NET有什么关联没有?
thanks。
Monitor相当于CriticalSection?
如何在C#中实现象MFC中的EnterCriticalSection、LeaveCriticalSection的功能?
我需要的正是这个。
Wait()直接就把线程移到等待队列了,而P原语有一个判断。
“调用线程不拥有互斥体”异常也是正确的,你没有调用互斥体的WaitOne方法就调用ReleaseMutex方法就是这个结果啊!
你说的对。Mutex有个所有权问题,只有拥有者才能释放,所以我的代码出错。
我正在尝试用Monitor...
ReaderWriterLock能实现互斥,但是可控性太差。
无法实现读/写者优先的要求。谁能介绍一下如何用Monitor替代MFC中的EnterCriticalSection和LeaveCriticalSection。
我用Monitor.Enter和Monitor.Exit程序运行时死锁。
的确象你说的p,v操作是有一个判断,但是我的意思是在c#中调用wait()和pulse()
要实现的功能就是和操作系统中用p,v来互斥操作一样to 楼主
你说的mfc中的两个方法我没用过,不过你可以说说你想实现的具体功能,不过
按照你上面的描述,我说的方法肯定行
我现在需要象EnterCriticalSection、LeaveCriticalSection那样的,不需要由同一个
线程执行,并且当某个线程LeaveCriticalSection以后,阻塞在EnterCriticalSection
上的线程能马上得到通知的机制。Monitor的Wait、Pulse又必须写在Enter、Exit内,而且语义和P、V原语不大一致。
想不懂.net为什么不沿用原来的机制。
由于管程比信号量高级,所有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。非常好用。
MSDN、Google上都没有找到Monitor实现Semaphore的相关说明。
希望这个帖子能给和我一样遇到这个问题的朋友一点帮助。
谢谢大家,揭贴。