如何获取唯一的线程标识符?

3
在尝试构建一个“仿真”的可重入互斥锁时,我需要一个对每个线程都是唯一的标识符。我可以通过thread::current获取当前线程,但是Thread似乎没有任何可用(或被滥用)作为标识符的东西。
对于我的目的,我认为标识符可以在线程退出后被重用,虽然我也会对不重用标识符的答案感兴趣,因为这些可能在其他情况下有用。

1
标识符在线程结束后是否需要保持唯一性,或者另一个新创建的线程可以重用先前已经终止的线程的线程ID?对于可重入互斥锁,我认为重用不会成为问题,但我宁愿确定一下。 - Matthieu M.
@MatthieuM。好问题!我无法想象一个重复使用的ID如何会对我的情况造成问题,但也许我没有想得够深入;-) - Shepmaster
3个回答

3

另一种方法是,如果你能使用libc

fn get_thread_id() -> libc::pthread_t {
    unsafe { libc::pthread_self() }
}

pthread_t 会根据平台映射到正确的目标。


1
虽然这样做是可行的,但在Windows上的成功率相当低。有一个基于同样思路的crate,但它也兼容Windows。 - Shepmaster

1

虽然使用线程系统内置的东西会更好,但一个解决方案是跟踪我们自己的线程ID。这些可以使用原子和线程本地变量的组合来创建:

use std::sync::atomic;
use std::thread;

static THREAD_COUNT: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
thread_local!(static THREAD_ID: usize = THREAD_COUNT.fetch_add(1, atomic::Ordering::SeqCst));

fn thread_id() -> usize {
    THREAD_ID.with(|&id| id)
}

// Example usage

fn main() {
    println!("{}", thread_id());

    let handles: Vec<_> = (0..10).map(|_| { 
        thread::spawn(|| {
            println!("{}", thread_id());
        })
    }).collect();

    for h in handles { h.join().unwrap() }
}

1
有趣的是,线程本地实现很可能会为其内部工作分配一个线程ID。 - Matthieu M.

0
但是Thread似乎没有任何可用(或滥用)作为标识符的东西。这在Rust 1.19中通过Thread::id得到了纠正。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接