什么是C#的GIL版本?

Tha*_*tos 8 c# python java gil

在CPython的当前实现中,存在称为"GIL"或"Global Interpreter Lock"的对象.它本质上是一个互斥锁,可以防止两个Python线程同时执行Python代码.这可以防止两个线程破坏Python解释器的状态,但也可以防止多个线程真正一起执行.基本上,如果我这样做:

# Thread A
some_list.append(3)
# Thread B
some_list.append(4)
Run Code Online (Sandbox Code Playgroud)

我无法破坏列表,因为在任何给定时间,只有其中一个线程正在执行,因为它们必须持有GIL才能执行此操作.现在,列表中的项目可能会以某种不确定的顺序添加,但关键是列表没有损坏,并且总会添加两件事.

所以,现在到C#.C#基本上面临与Python相同的问题,那么,C#如何阻止这种情况呢?如果有人知道的话,我也有兴趣听Java的故事.


澄清:我对没有显式锁定语句的情况感兴趣,特别是对VM.我知道Java和C#都存在锁定原语 - 它们也存在于Python中:GIL不用于多线程代码,只是为了保持解释器的理智.我对以上的直接等价感兴趣,所以,在C#中,如果我能够记得足够...... :-)

List<String> s;
// Reference to s is shared by two threads, which both execute this:
s.Add("hello");
// State of s?
// State of the VM? (And if sane, how so?)
Run Code Online (Sandbox Code Playgroud)

这是另一个例子:

class A
{
    public String s;
}
// Thread A & B
some_A.s = some_other_value;

// some_A's state must change: how does it change?
// Is the VM still in good shape afterwards?
Run Code Online (Sandbox Code Playgroud)

我不打算写坏C#代码,我理解这些lock陈述.即使在Python中,GIL也不会为您提供神奇的多线程代码:您仍然必须锁定共享资源.但是GIL阻止了Python的"VM"被破坏 - 这是我感兴趣的行为.

Ign*_*ams 11

大多数支持线程的其他语言都没有Python GIL的等价物; 它们要求您隐式或显式地使用互斥锁.

  • 我不会考虑用一种语言来编写多线程程序,这种语言不能保持其基本数据结构本身的一致性,并且依赖程序员在任何地方添加锁. (6认同)
  • 此外,我甚至不会考虑使用像GIL这样的语言编写多线程代码.这就像一个闪烁的霓虹灯,上面写着:"多线程太难了;我们放弃了." (3认同)
  • @JoelMueller:Python*语言*中的哪个地方指定了GIL? (3认同)
  • 你宁愿使用一种语言,在这种语言中,一次不可能发生多件事情?这不是一个多线程程序.不,"在任何地方添加锁"并不是唯一的选择. (2认同)
  • "VM的状态"究竟是什么意思?唯一重要的状态是由多个线程操纵的特定对象的状态.如果VM需要进行垃圾收集,它会暂停所有线程,直到GC完成.虚拟机不会被多个线程弄乱对象实例而损坏 - 只有该对象的数据可能被破坏.将锁定仅放置在您需要的位置,而不是对绝对所有内容进行隐式锁定,可以显着提高性能. (2认同)

Pie*_*kel 4

使用锁,你可以这样做:

lock(some_list)
{
    some_list.Add(3);
}
Run Code Online (Sandbox Code Playgroud)

在线程 2 中:

lock(some_list)
{
    some_list.Add(4);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,该lock语句确保该lock语句内的对象some_list一次只能由一个线程访问。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx 。

  • 结果是无法保证会发生什么。它**不会**破坏虚拟机的状态。然而,它可能会破坏您正在调用方法的实例的状态。当 MSDN 页面中没有特别说明时,一般规则是实例方法必须包含在“lock”中,而静态方法不必包含在“lock”中。 (2认同)