在当前的 CPython 实现中,有一个称为“GIL”或“全局解释器锁”的对象。它本质上是一个互斥锁,可以防止两个 Python 线程同时执行 Python 代码。这可以防止两个线程破坏 Python 解释器的状态,同时也可以防止多个线程真正一起执行。本质上,如果我这样做:
# Thread A
some_list.append(3)
# Thread B
some_list.append(4)
我不能破坏列表,因为在任何给定时间,只有其中一个线程正在执行,因为它们必须持有 GIL 才能执行此操作。现在,列表中的项目可能会以某种不确定的顺序添加,但重点是列表不会损坏,并且总是会添加两件事。
那么,现在转向 C#。 C# 本质上面临着与 Python 相同的问题,那么,C# 如何防止这种情况发生呢?如果有人知道的话,我也有兴趣听听 Java 的故事。
说明:我对没有显式锁定语句时会发生什么感兴趣,尤其是对于虚拟机。我知道 Java 和 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?)
这是另一个例子:
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?
我不想编写糟糕的 C# 代码,我理解 lock< /代码> 语句。即使在 Python 中,GIL 也不会为您提供神奇的多线程代码:您仍然必须锁定共享资源。但是 GIL 可以防止 Python 的“VM”被损坏——我对这种行为感兴趣。
In the current implementation of CPython, there is an object known as the "GIL" or "Global Interpreter Lock". It is essentially a mutex that prevents two Python threads from executing Python code at the same time. This prevents two threads from being able to corrupt the state of the Python interpreter, but also prevents multiple threads from really executing together. Essentially, if I do this:
# Thread A
some_list.append(3)
# Thread B
some_list.append(4)
I can't corrupt the list, because at any given time, only one of those threads are executing, since they must hold the GIL to do so. Now, the items in the list might be added in some indeterminate order, but the point is that the list isn't corrupted, and two things will always get added.
So, now to C#. C# essentially faces the same problem as Python, so, how does C# prevent this? I'd also be interested in hearing Java's story, if anyone knows it.
Clarification: I'm interested in what happens without explicit locking statements, especially to the VM. I am aware that locking primitives exist for both Java & C# - they exist in Python as well: The GIL is not used for multi-threaded code, other than to keep the interpreter sane. I am interested in the direct equivalent of the above, so, in C#, if I can remember enough... :-)
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?)
Here's another example:
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?
I'm not looking to write bad C# code, I understand the lock
statements. Even in Python, the GIL doesn't give you magic-multi-threaded code: you must still lock shared resources. But the GIL prevents Python's "VM" from being corrupted - it is this behavior that I'm interested in.
发布评论
评论(6)
大多数支持线程的其他语言都没有相当于 Python GIL 的工具;它们要求您隐式或显式地使用互斥锁。
Most other languages that support threading don't have an equivalent of the Python GIL; they require you to use mutexes, either implicitly or explicitly.
使用锁,您可以执行以下操作:
在线程 2 中:
lock
语句确保lock
语句内的对象,在本例中为some_list
,一次只能由一个线程访问。请参阅 http://msdn.microsoft.com/en-us /library/c5kehkcz(VS.80).aspx 了解更多信息。Using lock, you would do this:
and in thread 2:
The
lock
statement ensures that the object inside thelock
statement,some_list
in this case, can only be accessed by a single thread at a time. See http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx for more information.C# 没有相当于 Python 的 GIL。
根据其中一项讨论 -
注意:其他实现(例如 IronPython)没有 GIL。
C# does not have an equivalent of GIL to Python.
As per one of the discussion -
Note: Other implementation like IronPython do not have GIL.
查看Java 等效文档可能会有所帮助您正在讨论的班级:
It may be instructive to look at the documentation for the Java equivalent of the class you're discussing:
大多数复杂的数据结构(例如列表)在不锁定多个线程的情况下使用时可能会被损坏。
由于引用的更改是原子的,因此引用始终保持有效引用。
但与安全关键代码交互时存在问题。因此,关键代码使用的任何数据结构大多是以下之一:
例如,关键代码不能信任可从不受信任的代码访问的列表。如果它在列表中传递,它必须创建一个私有副本,对该副本进行先决条件检查,然后对该副本进行操作。
Most complex datastructures(for example lists) can be corrupted when used without locking in multiple threads.
Since changes of references are atomic, a reference always stays a valid reference.
But there is a problem when interacting with security critical code. So any datastructures used by critical code most be one of the following:
For example critical code cannot trust a list accessible from untrusted code. If it gets passed in a List, it has to create a private copy, do it's precondition checks on the copy, and then operate on the copy.
我将大胆猜测一下这个问题的真正含义……
在 Python 中,解释器中的数据结构会被损坏,因为 Python 使用了一种引用计数形式。
C# 和 Java 都使用垃圾收集,事实上,它们在执行完整堆收集时确实使用全局锁。
数据可以在“代”之间进行标记和移动,而无需锁定。但要真正清理干净,一切都必须停止。希望这是一个非常短暂的停留,但也是一个完整的停留。
以下是截至 2007 年有关 CLR 垃圾回收的有趣链接:
http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD !1104.entry
I'm going to take a wild guess at what the question really means...
In Python data structures in the interpreter get corrupted because Python is using a form of reference counting.
Both C# and Java use garbage collection and in fact they do use a global lock when doing a full heap collection.
Data can be marked and moved between "generations" without a lock. But to actually clean it up everything must come to a stop. Hopefully a very short stop, but a full stop.
Here is an interesting link on CLR garbage collection as of 2007:
http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry