Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 调用方/回溯跟踪超出线程_Ruby_Multithreading_Backtrace - Fatal编程技术网

Ruby 调用方/回溯跟踪超出线程

Ruby 调用方/回溯跟踪超出线程,ruby,multithreading,backtrace,Ruby,Multithreading,Backtrace,据我所知,只可能获取当前线程中的调用方/回溯信息部分;在此之前的任何内容(在创建当前线程的线程中)都将被切断。下面举例说明这一点;a称为b,称为c,创建了名为d的线程的事实被切断: def a; b end def b; c end def c; Thread.new{d}.join end def d; e end def e; puts caller end a # => this_file:4:in `d' # this_file:3:in `block in c' 这一特

据我所知,只可能获取当前线程中的调用方/回溯信息部分;在此之前的任何内容(在创建当前线程的线程中)都将被切断。下面举例说明这一点;
a
称为
b
,称为
c
,创建了名为
d
的线程的事实被切断:

def a; b end
def b; c end
def c; Thread.new{d}.join end
def d; e end
def e; puts caller end

a
# => this_file:4:in `d'
#    this_file:3:in `block in c'
  • 这一特性的原因是什么
  • 有没有办法获取当前线程之外的调用方/回溯信息

  • 你两个问题的答案其实是一样的。考虑一个稍微多一些牵涉的主线。主线程不再简单地等待派生线程在
    c
    中结束,而是继续调用其他函数,甚至可能从
    c
    返回并继续处理它的事务,而派生线程继续处理它的事务

    这意味着主线程中的堆栈在
    d
    中启动的线程生成后发生了更改。换句话说,在调用调用调用方时,主线程中的堆栈不再处于创建次线程时的状态。没有办法安全地走回到堆栈上超过这一点

    简言之:

  • 生成线程的堆栈将不会保持在生成线程时的状态,因此返回到线程自身堆栈的开头之外是不安全的

  • 不,因为线程背后的全部思想是它们是(伪)并行的,所以它们的堆栈是完全不相关的

  • 更新:

    正如注释中所建议的,当前线程的堆栈可以在创建时复制到新线程。这将保留导致创建线程的信息,但解决方案并非没有自己的问题集

  • 线程创建速度将减慢。如果能从中获得什么好处的话,那也没关系,但在这种情况下,是吗

  • 从线程入口函数返回意味着什么

    • 它可以返回到创建线程的函数并继续运行,就像它只是一个函数调用一样——只是它现在在第二个线程中运行,而不是在原始线程中运行。我们想要吗
    • 即使线程不在调用堆栈的顶部,也可能会有一些魔法确保线程终止。这将使线程入口函数上方的调用堆栈中的信息无论如何都不正确
  • 在对每个线程的堆栈大小有限制的系统上,您可能会遇到线程堆栈不足的问题,即使线程本身没有太多使用

  • 可能还有其他的场景和特性可以考虑,但是线程创建时使用自己的空堆栈开始的方式使得模型既简单又可预测,而不会在调用堆栈中留下任何有用的信息。

    我想我已经找到了答案

    可以从线程外部对线程执行的操作不仅仅是创建线程。除了创建之外,您还可以进行唤醒等操作,因此不清楚调用方应该将哪些操作归为其一部分。例如,假设有一个线程:

    1: t = Thread.new{
    2:   Thread.stop
    3:   puts caller
    4: }
    5: t.wakeup
    
    线程
    t
    在第1行创建,但在第2行它自己进入睡眠状态,然后在第5行唤醒。因此,当我们在第3行“代码>调用方< /代码>,并考虑线程之外的调用方部分时,不清楚<代码>线程。第1行中的新< /代码>应该是它的一部分,或者<代码> T.WaKeUP 5行应该是它的一部分。因此,在当前线程之外没有明确的调用方概念


    然而,若我们定义了一个清晰的概念,那个么调用线程之外的调用方就有可能理解。例如,始终将调用方添加到线程的创建中可能是有意义的。否则,添加导致最近的
    唤醒或创建的调用方可能有意义。这取决于定义。

    您的回答解释了当前实现无法返回信息的原因。但我不认为这在原则上是不可能的。如果每个线程在创建时将调用方信息复制到创建时的位置,并将其保存在自己内部,那么不可能从该线程中获取整个信息吗?我错了吗?我觉得我甚至可以在Ruby级别实现它。没有什么是不可能的,但是有什么可以获得的吗?Se更新了答案。