且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

列表与LT; T>线程安全问题

更新时间:2021-10-18 15:25:35



" Rainer Queck" <太阳神**** @ noemail.noemail>在消息中写道

news:ui ************** @ TK2MSFTNGP10.phx.gbl ...

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:ui**************@TK2MSFTNGP10.phx.gbl...
Hi NG,
让我们假设一个通用列表:
List< MyTyp> aList = new List< MyType>();

如果一个线程从列表中删除元素,例如
MyTyp x = aList [0];
aList,那会不会有问题。删除(x);

在同一个momen中,另一个线程添加一个元素,如
MyType y = new MyType();
aList.Add(y);

假设这两个操作组合好可以安全吗?
Hi NG,

one more question about thread safety of generic lists.
Let''s assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?




否 - 肯定会失败。
>
这是一个经典的线程问题,并且将线程安全Q< T>

拼凑在一起是一个很好的练习,你应该为自己解决这个问题。


概述你需要在访问时保护q;有一个机制

来阻止从空q中移除;有一种机制可以在添加到aq时取消阻止其他

线程,如果你想要最大q大小,可能会更多。



No - it will definitely fail.

This is a classic threading problem and cobbling together a threadsafe Q<T>
is a good exercise that you should really work out for yourself.

In outline you need to protect the q whilst accessing it; have a mechanism
to block if removing from an empty q;have a mechanism to unblock other
threads when adding to a q and possibly more if you want a maximum q size.


你好尼克,


感谢您的回复!
Hi Nick,

thanks for responding!
关于通用列表的线程安全性的另一个问题。
让我们假设一个通用列表:
List< MyTyp> aList = new List< MyType>();

如果一个线程从列表中删除元素,例如
MyTyp x = aList [0];
aList,那会不会有问题。删除(x);

在同一个momen中,另一个线程添加一个元素,如
MyType y = new MyType();
aList.Add(y);

假设这两个操作组合好可以安全吗?
one more question about thread safety of generic lists.
Let''s assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?



不 - 它肯定会失败。



No - it will definitely fail.



这就是我的预期,只是想确定。


这是线程安全吗?:


列表< MyTyp> aList = new List< MyType>();


//一个线程从列表中删除元素,如

Monitor.Enter(aList)

试试

{

MyTyp x = aList [0];

aList.Remove(x);

}

终于{

Monitor.Exit(aList)

}


/ /在同一个momen中,另一个线程添加了一个元素,如


MyType y = new MyType();

Monitor.Enter(aList)

尝试

{

aList.Add(y);

}

finally {

Monitor.Exit(aList);

}


问候

Rainer


This is what I expected, just wanted to make sure.

Would this be thread safe?:

List<MyTyp> aList = new List<MyType>();

// one thread removes elements from the list like
Monitor.Enter(aList)
try
{
MyTyp x = aList[0];
aList.Remove(x);
}
finally{
Monitor.Exit(aList)
}

// While in the same momen a other thread adds a element like

MyType y = new MyType();
Monitor.Enter(aList)
try
{
aList.Add(y);
}
finally{
Monitor.Exit(aList);
}

Regards
Rainer




" Rainer Queck" &LT;太阳神**** @ noemail.noemail&GT;在消息中写道

新闻:uW ************** @ TK2MSFTNGP10.phx.gbl ...

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:uW**************@TK2MSFTNGP10.phx.gbl...
嗨尼克,

感谢您的回复!
Hi Nick,

thanks for responding!
还有一个关于通用列表的线程安全性的问题。
让我们假设一个通用列表:
列表< MyTyp> aList = new List< MyType>();

如果一个线程从列表中删除元素,例如
MyTyp x = aList [0];
aList,那会不会有问题。删除(x);

在同一个momen中,另一个线程添加一个元素,如
MyType y = new MyType();
aList.Add(y);

假设这两个操作组合好可以安全吗?
one more question about thread safety of generic lists.
Let''s assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?



不 - 它肯定会失败。



No - it will definitely fail.


这是什么我想,只是想确定一下。

这会是线程安全吗?:

List< MyTyp> aList = new List< MyType>();

//一个线程从列表中删除元素,如
Monitor.Enter(aList)
尝试
{
MyTyp x = aList [0];
aList.Remove(x);
}
最后{
Monitor.Exit(aList)
}

//在同一个momen中,另一个线程添加了一个元素,如

MyType y = new MyType();
Monitor.Enter(aList)
尝试
{
aList.Add(y);
}
终于{
Monitor.Exit(aList);
}
>问候
Rainer


This is what I expected, just wanted to make sure.

Would this be thread safe?:

List<MyTyp> aList = new List<MyType>();

// one thread removes elements from the list like
Monitor.Enter(aList)
try
{
MyTyp x = aList[0];
aList.Remove(x);
}
finally{
Monitor.Exit(aList)
}

// While in the same momen a other thread adds a element like

MyType y = new MyType();
Monitor.Enter(aList)
try
{
aList.Add(y);
}
finally{
Monitor.Exit(aList);
}

Regards
Rainer




首先是锁定比Monitor更整洁(它在幕后使用Monitor)

锁定(aList)

{

//做东西

}


其次你的解决方案是可以的,但它避免了与问题有关的主要问题b $ b问题当我尝试

取出一些东西时,如果清单是空的怎么办?


1)你不能测试空的锁定外面在wgich你得到的地区

元素

2)你必须要么返回一些表明它是空的东西或者等待

直到它不是'' t空,这将需要等待和脉冲方法在

监视器上

3)如果你有一个固定长度的列表队列,那么同样的问题适用于

添加方法



firstly"lock" is neater than Monitor (it uses Monitor behind the scenes)
lock(aList)
{
// do stuff
}

secondly you''re solution is OK as far as it goes but it avoids the main
issue which is to do with the question "what if the list is empty when I try
to take something off it?"

1) You cannot test for empty outside of the locked region in wgich you get
the element
2) You must either return something indicating that it was empty or wait
until it isn''t empty which will require the Wait and Pulse methods on the
Monitor
3) If you have a fixed length list queue then the same issues apply to the
add method