是否有被孩子Thread对象自动继承任何可编程数据?可编程、对象、孩子、数据

2023-09-03 22:17:55 作者:昭华倾覆三生梦

我有一个想法,为解决枚举.NET托管线程的问题,并跟踪线程祖先(哪个线程创建了其他线程)。

I had an idea for solving the problem of enumerating managed threads in .Net and for tracking thread ancestry (which thread created which other thread).

如果有可能,标记与程序员的决策,它会自动复制到孩子在创建时,线程对象的线程对象,有可能使用该标签在创建新线程时跟踪,谁创造了他们等灵感来自于UNIX,其中,当一个进程分叉,它继承打开的文件句柄,等等。如果有一些数据块是1)线程本地或绑在Thread对象和2)是自动复制到新主题; 3)是可以修改的,这将是一个良好的开端。

If it were possible to tag a Thread object with an object of the programmer's making that is automatically copied to children threads when they are created, it might be possible to use that tag to track when new threads are created, who created them, etc. The inspiration came from unix, where, when a process is forked, it inherits open file handles, etc. If there were some piece of data that is 1) thread-local or tied to a Thread object and 2) is automatically copied to new threads and 3) is modifiable, that would be a good start.

我猜,我们将不得不使用反射来访问的一些启动链,因为大部分是我的,可能是有用的线程看到的是,否则锁定了线程对象的成员,但它是一个开始。我不知道如何聪明的这种做法虽然。

I'm guessing that we'll have to use reflection to access members of some of the Thread object that starts the chain because most of what i see in the thread that might be useful is otherwise locked up, but it's an start. I'm not sure how wise this approach is though.

编辑: 我想我会解释一下我的使用情况更好,因为我不认为任何人可以理解的。

I think I'll explain my use case better because I don't think anybody understands.

我知道明确跟踪线程,我在codeI广泛做了自己之前。这不是问题。

I know about tracking threads explicitly, which I've done widely in code i own before. That's not the problem.

基本上,我想实现一个线程组上下文,很多相同的方式,净有一个AppDomain上下文,一个远程上下文的 [1] 和组装线组合,当地环境的 [2]

Basically, I'm trying to implement a 'thread-group-context', much in the same way that .Net has an appdomain-context, a remoting context [1] and an assembly-thread combination-local context [2].

对于一个给定的组从一个共同的主线已产生的线程,我想与该分组的信息相关联。虽然我明白,.NET不具备这个概念(否则我也没问题!),它并没有改变,在每一个净托管线程是由一个且只有一个其他托管线程,从而创造了一个事实,可以以树结构进行绘制。

For a given group of threads that were spawned from a common thread, I want to associate information with that grouping. While I understand that .Net doesn't have this concept (else I would have no problem!), it doesn't change the fact that every managed thread in .Net was created by one and only one other managed thread, and thus, can be drawn in a tree structure.

我想解决的问题是这样的:我有一个API,有一个上下文对象。这个API调用到code大的外部库,做真正的工作,并不会因此从它创建一个线程开始。外部没有明确可以获得API上下文对象的副本,但它需要之一,以使对API调用。因为它不具有一个参考到API上下文对象,它不能使这些调用。就目前情况来看,外部库确实需要拨打电话,而这样做,它查找当前上下文对象在一个单一的静态字段,这意味着有只能是每个AppDomain我的API的一个实例。我想解决这个问题。

The problem I am trying to solve is thus: I have an API, that has an context object. This API calls into a large external library of code that does real work, and does so starting from a thread of its creation. That external does not explicitly get a copy of the API context object, however it would need one in order to make calls on the API. Since it does not have a reference to the API context object, it cannot make these calls. As things stand today, the external library does need to make calls, and to do so it looks up the current context object in a single static field, meaning that there can only be one instance of my API per AppDomain. I wish to fix this.

这个外部库部分超出我的控制,我的API和外部库之间的接口没有明确传递上下文对象。截至目前为止,时所需的外部库能够调用的API,它看起来在一个静态字段在我的API来获取一个引用上下文对象。

This external library is partly out of my control, and the interface between my API and the external library does not explicitly pass the context object. Up until now, when the external library needed to make calls into the API, it would look at a static field in my API to get a reference to the context object.

现在的问题是那么最终的可执行文件只能有每个AppDomain我的API会议的一个实例,因为我们使用的是静态字段来传递上下文对象对外部库(主力)code

The problem is then that a final executable can only have one instance of my API session per AppDomain, because we're using static fields to pass the context object to the external library (workhorse) code.

一种选择是让我的API一个GetContextObject()方法。当API产卵运行外部库code中的线程,它会记得在一个共享的静态辞典该线程。当外部库code调用GetContextObject(),它看起来了一下它的线程上运行,并返回正确的上下文对象的线程。

One option is to make a GetContextObject() method in my API. When the API spawns the thread to run the external library code, it would remember that thread in a shared static dictionary. When the external library code calls GetContextObject(), it would look up what thread it is running on and return the proper context object for that thread.

如果外部库code从未创建自己的线程,那么我也没问题,我总是有线程的上下文100%正确的映射。但是,外部库确实让自己的线程,这样做没有我的API意识到。当API接收从这些线程调用,它将不知道什么上下文对象放弃,并有猜测 - 如果只有一个对象注册的情况下,它会使用,否则,它抛出一个异常说,它不能告诉你。

If the external library code never created its own threads, then I'd have no problem, I'd always have a 100% correct mapping of thread to context. However, the external library does make its own threads, and does so without my API being aware. When the API receives a call from those threads, it won't know what context object to give up, and has to guess - if there's only one context object registered, it uses that, otherwise, it throws an exception saying it can't tell you.

如果我能有标记,以线程由由父线程创建的线程继承的对象数据,那么我可以实现这个跟踪系统。

If I could have data tagged to thread objects that is inherited by threads created by that parent thread, then I could implement this tracking system.

另外,外部库不使用线程池。

Also, the external library does not use the thread pool.

基本上,我的选择是这样的:

Basically, my options are thus:

1)重新设计我的API和外部库之间的接口传递在上下文对象中,并重新设计外部库正确绕过此上下文对象。通过〜百万LOC涉及trundling。

1) Redesign the interface between my API and the external library to pass in the context object, and redesign the external library to correctly pass around this context object. Involves trundling through ~1 million LOC.

1A)直接使用Thread对象禁止外部库,而是要求他们用自己的MyApiThread对象,创建时,将自身添加到我的自定义跟踪机制。需要改变较少code比选项#1的外部库,但仍涉及到大量的返工。

1a) Forbid the external library from directly using the Thread object, and instead require them to use my own MyApiThread object that, when created, adds itself to my custom tracking mechanism. Requires changing less code in the external library than option #1, but still involves a lot of rework.

2)强制我的API消费者在新的AppDomain启动每个API会话,这样我可以存储我的上下文对象的静态字段(这是解决方案今天)。 AppDomain中涉及大量的开销,我不希望在我的用户,迫使这一点。

2) Force the consumer of my API to start each API session in a new AppDomain so that I can store my context object in a static field (this is the 'solution' today). AppDomains involve a lot of overhead and I do not wish to force this upon my users.

3)找到一个方法来跟踪线程的祖先才能够正确的上下文对象从基础调用线程上的外部库返回code调用。这是这篇文章的主题。

3) Find a way to track thread ancestry to be able to return the correct context object to the code calling from the external library based on the calling thread. This is the subject of this post.

要那些说,Windows没有父子线程的概念,你是大错特错了 - 那是无关紧要的。 DOTNET的不是Windows专用系统,并且它的设计理念是从机器分离它和操作系统运行它,这就是为什么净存在Linux和Solaris,FreeBSD的单声道的形式。此外,Java的确实有螺纹的祖先的这个概念,我需要和Java在Windows上实现的,因此这是一个非常可能的,合理的概念。虽然我认识到.NET API具有一定的特定于Microsoft的弯了,这才知道,在很大程度上,.NET和Windows是独立的。

To those saying that Windows does not have a concept of child-parent threading, you are off base - that is irrelevant. DotNet is not a Windows-only system, and its very design was to isolate it from the machine and OS it is running on, which is why .Net exists for Linux, Solaris, FreeBSD in the form of Mono. Furthermore, Java does have the very concept of thread ancestry that I need, and Java is implemented on Windows, thus this is a very possible and reasonable concept. While I realize that the .Net api has a certain Microsoft-specific bend to it, realize that, largely, .Net and Windows are independent.

推荐答案

其实,我会让我的评论一个答案,并指出你的杰弗里里希特。

In fact, I'll make my comment an answer and point you at Jeffrey Richter.

在CallContext中类为您提供了存储数据的逻辑执行路径,它可以跨越线程和应用程序域的能力。

The CallContext class gives you the ability to store data for a "logical execution path", which can cross threads and AppDomains.