.NET 中的 Erlang 风格的轻量级进程
有没有办法在.NET中实现Erlang风格的轻量级进程?
我发现了一些实现 Erlang 消息传递模型(参与者模型)的项目。例如,Axum。但我没有发现任何关于轻量级流程实施的信息。我的意思是在单个操作系统线程或操作系统进程的上下文中运行的多个进程。
Is there any way to implement Erlang-style light-weight processes in .NET?
I found some projects that implement Erlang messaging model (actors model). For example, Axum. But I found nothing about light-weight processes implementation. I mean multiple processes that run in a context of a single OS-thread or OS-process.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为 F# MailboxProcessor 就是您正在寻找的 Alexey。使用 MailboxProcessor,您可以在一个 .NET 进程中定义数以万计的代理,就像您可以在 Erlang 中生成数以万计的轻量级进程一样。
这个MSDN 帖子 是一个很好的介绍。
如果您是从 Erlang 背景转向 .NET 的,请记住,您将错过很多 OTP 的好处(管理器、位置透明性、mnesia,...)。
I think the F# MailboxProcessor is what you're looking for Alexey. Using the MailboxProcessor you can define tens of thousands of agents within one .NET process much like you can spawn tens of thousands of lightweight processes in Erlang.
This MSDN post by Don Syme is a great introduction.
If you're coming to .NET from an Erlang background keep in mind you're going to be missing lots of OTP goodies (supervisors, location transparency, mnesia, ...).
CLR 可以被托管并公开主机实现其自己的任务抽象的机制。理论上,它们可以是线程、光纤、LWP - 只要主机实现 必要的 接口。
做到正确有点困难。 MS 抓住了这个机会,以 SQL Server Fiber 模式托管 CLR。
在最后一刻,出现了一些压力错误,因此他们根据 乔·达菲和迪诺·维兰德(谁运行了在他的博客上编写了一个自定义 CLR 主机,该主机通过纤程实现了自己的任务抽象)。< br>
现在缺少一些管道 -
ICLRTask::SwitchOut()
- 即使有人解决了这个问题,在压力测试迭代中攻击 MS 的相同错误也可能会困扰着冒险的灵魂。
假设所有问题都以某种方式得到解决,并且整个运行时已准备好在纤程、LWP 等上运行。 P/Invoke 仍然存在可能调用阻塞操作的问题。如果没有内核的支持,这种调度是很难做到的。
64 位版本的 Windows 7 和 Windows 2008 Server R2 已解决此问题。现在有用户模式调度可以产生如果调用在内核中阻塞,则控制权返回到用户模式 - 与内核模式相反 - 调度程序。此外,这些用户模式调度线程是具有自己的 TLS 的真实线程。这些都是巨大的改进,使许多光纤模式令人头痛的问题迎刃而解。
目前,使用 UMS< /a> 在 并发运行时 中 < a href="http://msdn.microsoft.com/en-us/library/dd504870(VS.100).aspx" rel="noreferrer">可用于 C++,是 C 运行时库 (CRT) 的一部分< /a>.
后者意味着您可以在 Visual Studio 2010 中直接使用它。
The CLR can be hosted and exposes mechanisms for the host to implement its own task abstraction. Theoretically, they can be threads, fibers, LWPs - anything as long as the host implements the necessary interfaces.
Getting it right is somewhat hard. MS took a chance on it in order to host the CLR in SQL Server Fiber Mode.
At the last moment, there were some stress bugs, so they pulled the plug on it according to Joe Duffy and Dino Vhieland (who ran a series about writing a custom CLR host that implements its own task abstraction - with fibers - on his blog).
Right now there is some plumbing missing -
ICLRTask::SwitchOut()
- and even if one gets around that, the same bugs that hit MS at the stress test iteration would probably haunt the adventurous soul as well.Suppose for a moment that all the problems are somehow fixed and the whole runtime is prepared to run on fibers, LWPs, whatever. There is still the problem of P/Invoke that might potentially call into blocking operations. This kind of scheduling is hard to do without kernel support.
This is addressed in the 64bit versions of Windows 7 and Windows 2008 Server R2. There is now User-Mode Scheduling that can yield control back to a user-mode - as opposed to kernel-mode - scheduler if a call blocks in the kernel. Also, these user-mode scheduled threads are real threads with their own TLS. These are great improvements and make many of the fiber mode headaches go away.
Right now, UMS is utilized in the Concurrency Runtime that is available for C++ and is part of the C Runtime Library (CRT).
The latter means that you can use it out of the box with Visual Studio 2010.
您看过 retlang 吗?我只读过它,但我没有用它做任何事情,但是......
Have You had a look at retlang? I only read about it, but I didn't do anything with it, yet...
Erlang进程就像并行运行方法,但是erlang变量只能绑定一次,因此它是线程安全的,而C#中则没有。
所以在 C# 中你需要两件事:线程安全和并行。
C#有System.Threading.Task,可以在vm中运行很多任务。 C# vm 将在不同的工作线程中调度这些任务。
但是任务不是线程安全的,你需要创建一个名为Actor的类,并将状态放在Actor中私有。
Actor 有一个 System.Threading.SynchronizationContext 和许多异步方法,就像这样。
当其他Actor调用该Actor中的async方法时,会创建一个任务,该任务将由vm调度。
您还需要实现一个可等待且线程安全的 SynchronizationContext。
这是一个线程安全的上下文。
让 SynchroniztionContext 可等待
SynchronizationContext 的 Awaiter
然后你会得到一个具有任务和线程安全的 Actor 类,就像 erlang 中的进程一样。
Erlang process is like running method parallelly, but erlang variable can only be bound once, so it is thread safe which is not in c#.
so you need two things in c#, thread safe and parallel.
C# has System.Threading.Task, you can run many tasks in vm. C# vm will scheduler these task in different working threads.
But task is not thread safe, you need to make a class called Actor, and put state private in the Actor.
The Actor has a System.Threading.SynchronizationContext, and many async Methods, like this.
When other Actors call the async method in this Actor, it will create a task, and the task will scheduled by vm.
You also need to implement a awaitable and thread safe SynchronizationContext.
this is a thread safe context.
make SynchroniztionContext awaitable
Awaiter for SynchronizationContext
then you get an Actor class with task and thread safe which like process in erlang.
这毫无意义。 “在单个操作系统线程或操作系统进程的上下文中运行的多个进程”在逻辑上是没有结论的。这基本上是一个逻辑应用程序级别的事情 - 您可以轻松地在 .NET 中重现它。但在操作系统级别上不存在“进程中的进程”之类的东西。
This makes no sense. "Multiple process that run in the context of a single OS thread or OS process" is logically inconclusive. THis is basically a logical application level thing - which you can easily repro in .NET. But there is no such thing like a "process within a process" on the OS level.