Skip to content

Commit 13975c3

Browse files
Watson1978claude
andcommitted
Thread: native_thread_id・thread_variables・each_caller_location を追加
実機で登場バージョンを確認し、#@SInCE で分岐した。 3.0 以前から存在: Thread#thread_variables スレッドローカル変数名の一覧 3.1 で追加: Thread#native_thread_id ネイティブスレッドの ID 3.4 で追加: Thread.each_caller_location 実行スタックを配列を作らず順に渡す 配置は関連メソッドの近くにした。thread_variables は thread_variable_set / thread_variable? の並び、native_thread_id は その直後、each_caller_location は Singleton Methods の Thread.stop の後。 thread_variables は既に Thread#thread_variable_set の例 (p thr.thread_variables) で使われていたが独立した項目が無かった。 その例の出力は rdoc 由来で [:dog, :cat] だったが、実機は挿入順の [:cat, :dog] を返す (2.7〜4.0 で確認)。新設の項目と食い違わないよう、 既存の例も [:cat, :dog] に直し、SEE に thread_variables を足した。 native_thread_id の返り値は OS 依存で、その他のプラットフォームでは NotImplementedError、ネイティブスレッドと未結合/切り離し済みなら nil に なることを記載した。死んだスレッドで nil が返ることは実機で確認済み。 each_caller_location は Kernel#caller_locations と同じ引数 (start/length, range) を取れることを C 実装 (vm_backtrace.c の ec_backtrace_range) で 確認し、シグネチャに反映した。 bitclust のデータベース生成を 3.0 / 3.1 / 3.3 / 3.4 / 4.0 で実行してエラーが 出ないこと、登録されるメソッドが 1 / 2 / 2 / 3 / 3 件と追加バージョンどおりに なることを確認済み。サンプルコードは対象の全バージョンで実行して出力を確認した。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5bcc2e4 commit 13975c3

1 file changed

Lines changed: 74 additions & 2 deletions

File tree

manual/api/_builtin/Thread.md

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,34 @@ a.join
259259

260260
- **SEE** [m:Thread#run], [m:Thread#wakeup]
261261

262+
#@since 3.4
263+
### def each_caller_location(start = 1, length = nil) {|location| ... } -> nil
264+
### def each_caller_location(range) {|location| ... } -> nil
265+
266+
現在の実行スタックの各フレームを、[c:Thread::Backtrace::Location] オブジェクトと
267+
してブロックに渡します。
268+
269+
[m:Kernel#caller_locations] と似ていますが、配列を作らずにブロックへ順に
270+
渡すため、目的のフレームが見つかった時点で処理を打ち切るような用途で
271+
無駄な生成を避けられます。
272+
引数の意味は [m:Kernel#caller_locations] と同じで、渡すフレームの範囲を指定できます。
273+
274+
nil を返します。
275+
276+
```ruby title="例"
277+
def foo
278+
Thread.each_caller_location do |location|
279+
p location.class # => Thread::Backtrace::Location
280+
break
281+
end
282+
end
283+
284+
foo
285+
```
286+
287+
- **SEE** [m:Kernel#caller_locations]
288+
#@end
289+
262290
### def DEBUG -> Integer
263291

264292
スレッドのデバッグレベルを返します。
@@ -1079,10 +1107,10 @@ thr = Thread.new do
10791107
Thread.current.thread_variable_set("dog", 'woof')
10801108
end
10811109
p thr.join # => #<Thread:0x401b3f10 dead>
1082-
p thr.thread_variables # => [:dog, :cat]
1110+
p thr.thread_variables # => [:cat, :dog]
10831111
```
10841112

1085-
- **SEE** [m:Thread#thread_variable_get], [m:Thread#\[\]]
1113+
- **SEE** [m:Thread#thread_variable_get], [m:Thread#thread_variables], [m:Thread#\[\]]
10861114

10871115
### def thread_variable?(key) -> bool
10881116

@@ -1103,6 +1131,50 @@ p me.thread_variable?(:stanley) # => false
11031131

11041132
- **SEE** [m:Thread#thread_variable_get], [m:Thread#\[\]]
11051133

1134+
### def thread_variables -> [Symbol]
1135+
1136+
スレッドローカル変数の名前を [c:Symbol] の配列で返します。
1137+
1138+
[注意]: [m:Thread#\[\]] でセットしたローカル変数(Fiber ローカル変数)は
1139+
対象ではない事に注意してください。
1140+
1141+
```ruby title="例"
1142+
thr = Thread.new do
1143+
Thread.current.thread_variable_set(:cat, 'meow')
1144+
Thread.current.thread_variable_set("dog", 'woof')
1145+
end
1146+
thr.join
1147+
p thr.thread_variables # => [:cat, :dog]
1148+
```
1149+
1150+
- **SEE** [m:Thread#thread_variable_get], [m:Thread#thread_variable?], [m:Thread#\[\]]
1151+
1152+
#@since 3.1
1153+
### def native_thread_id -> Integer | nil
1154+
1155+
self に対応するネイティブスレッドの ID を返します。
1156+
1157+
ID は OS に依存します(pthread_self(3) が返す POSIX スレッド ID とは異なります)。
1158+
1159+
* Linux では gettid(2) が返す TID です。
1160+
* macOS では pthread_threadid_np(3) が返すシステム全体で一意な整数の ID です。
1161+
* FreeBSD では pthread_getthreadid_np(3) が返すスレッド固有の整数の ID です。
1162+
* Windows では GetThreadId() が返すスレッド識別子です。
1163+
* その他のプラットフォームでは [c:NotImplementedError] が発生します。
1164+
1165+
スレッドがまだネイティブスレッドと結びついていない場合や、すでに切り離された
1166+
場合は nil を返します。
1167+
1168+
```ruby title="例"
1169+
p Thread.current.native_thread_id.class # => Integer
1170+
1171+
thr = Thread.new {}
1172+
thr.join
1173+
p thr.native_thread_id # => nil
1174+
```
1175+
1176+
#@end
1177+
11061178
### def pending_interrupt?(error = nil) -> bool
11071179

11081180
self の非同期例外のキューが空かどうかを返します。

0 commit comments

Comments
 (0)