Semaphore用在多线程的问题

heart33k 2018-12-06 05:45:22
private Semaphore m_Write = new Semaphore(50, 50, "WriteMap");
private Semaphore m_Read = new Semaphore(0, 50, "ReadMap");
private Queue q = new Queue();

public void Push_back(ref string str)
{
m_Write.WaitOne();
q.Enqueue(str);
m_Read.Release();
}
public bool Pop_front(out string s)
{
if (m_Read.WaitOne(10))
{
s = (string)q.Dequeue();
m_Write.Release();
return true;
}
s = null;
return false;
}
一个线程调用Push_back存数据,另一个线程调用Pop_front取数据,有时候可能全部数据读取出来,有时候会少一个或者多个,用q.Count能获取到元素个数不为0,但就是读不出来

public bool Pop_front(out string s)
{
if (q.Count > 0)
{
m_Read.WaitOne();
s = (string)q.Dequeue();
m_Write.Release();
return true;
}
s = null;
return false;
}
如果改为这样的话,就没问题了
为什么会这样呢,难道是m_Read.WaitOne(10)不可靠吗?
...全文
191 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
heart33k 2018-12-07
  • 打赏
  • 举报
回复
引用 2 楼 橘子皮zzz 的回复:
还有我感觉你这个可以用BlockingCollection
这个我倒可以试试 对了,就是因为Queue是不安全的,所以使用 m_Write.WaitOne(); q.Enqueue(str); m_Read.Release(); 这样做,以保证Queue安全 是这么理解吧
heart33k 2018-12-07
  • 打赏
  • 举报
回复
引用 1 楼 橘子皮zzz 的回复:
csdn还是能学到不少东西的,Semaphore我还是第一次看到有这么个玩意,小小百度研究了下 1:多线程下ConcurrentQueue是线程安全的,Queue 不是 2:你的第2个写法明显是错误的,多线下q.Count > 0这个判断就不是安全的 3:第一个写法m_Read.WaitOne(10)这句很奇怪,为什么要设置10ms,而不是其他时间,这个10ms时间有何意义?
1、可能是因为Queue不安全引起的 2、既然Queue是不安全的,那q.Count > 0肯定也是不安全的,是这么理解吧 3、10ms只是其中一个值,也可以设置其他值
heart33k 2018-12-07
  • 打赏
  • 举报
回复
我说的不一定对,我才知道还有Semaphore这个玩意 你说的m_Write.WaitOne(); q.Enqueue(str); m_Read.Release(); 也不一定能保证安全,因为你设置的是 private Semaphore m_Write = new Semaphore(50, 50, "WriteMap"); private Semaphore m_Read = new Semaphore(0, 50, "ReadMap"); m_Write 是50,不是1,如果是1的话可能是安全的[/quote] 你这么一说,倒提醒了我这个问题,也有可能是一边正在进数据,一边正在出数据
橘子皮... 2018-12-07
  • 打赏
  • 举报
回复
引用 2 楼 橘子皮zzz 的回复:
对了,就是因为Queue是不安全的,所以使用 m_Write.WaitOne(); q.Enqueue(str); m_Read.Release(); 这样做,以保证Queue安全 是这么理解吧
我说的不一定对,我才知道还有Semaphore这个玩意 你说的m_Write.WaitOne(); q.Enqueue(str); m_Read.Release(); 也不一定能保证安全,因为你设置的是 private Semaphore m_Write = new Semaphore(50, 50, "WriteMap"); private Semaphore m_Read = new Semaphore(0, 50, "ReadMap"); m_Write 是50,不是1,如果是1的话可能是安全的
橘子皮... 2018-12-06
  • 打赏
  • 举报
回复
还有我感觉你这个可以用BlockingCollection
橘子皮... 2018-12-06
  • 打赏
  • 举报
回复
csdn还是能学到不少东西的,Semaphore我还是第一次看到有这么个玩意,小小百度研究了下 1:多线程下ConcurrentQueue是线程安全的,Queue 不是 2:你的第2个写法明显是错误的,多线下q.Count > 0这个判断就不是安全的 3:第一个写法m_Read.WaitOne(10)这句很奇怪,为什么要设置10ms,而不是其他时间,这个10ms时间有何意义?

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧