https://github.com/yfractal/sdb_signal
这个主要是用来和 SDB 做性能对比的,是一个非常简单的 Stack Profiler。
因为简单,可以用来了解 Ruby 栈分析器的实现,以及如何用 Rust 写 Ruby extension。
一般的栈分析器,大体是先设置 signal,之后每隔一段时间,比如 1ms,触发 signal。在这个 signal handler 里,用 Ruby 内置的 rb_profile_thread_frames
扫描线程当前的栈。最后 rb_profile_frame_full_label
等方法获得 symbol。
用法:
require 'sdb_signal'
def foo(n)
if n == 0
sleep 10000000
else
foo(n - 1)
end
end
threads = []
5.times do |i|
threads << Thread.new do
foo(10)
end
end
SdbSignal.setup_signal_handler
SdbSignal.start_scheduler(threads)
# 这里没有输出,需要输出的话,可以找到相应的 Rust 代码打印或者打 log。
SDB 会稍微复杂一些,因为它的定位是 none blocking,不使用全局锁,也就没法用 Ruby 的 rb_profile_thread_frames
之类的方法,需要写扫描逻辑。架构上有一点优化,再就是并发性能上有一些考量(因为要做到 none blocking),比如用了 spinlock、memory barrier 之类的做并发控制。