libproc-rs icon indicating copy to clipboard operation
libproc-rs copied to clipboard

How can I get the current thread id?

Open zhongzc opened this issue 2 years ago • 7 comments

I tried libc::pthread_self. But it seems there is a fixed offset between the value fetched from libc::pthread_self and the value fetched from listpidinfo::<ListThreads>. Don't know why.

Code:

fn main() {
    use std::sync::{Mutex, Arc};
    use std::thread;
    use std::time::Duration;

    let mut ptids = Arc::new(Mutex::new(vec![unsafe { libc::pthread_self() }]));
    let mut threads = vec![];
    for _ in 0..3 {
        let ptids = ptids.clone();
        threads.push(thread::spawn(move || {
            let mut ptids = ptids.lock().unwrap();
            (*ptids).push(unsafe { libc::pthread_self() });
            drop(ptids);
            thread::sleep(Duration::from_millis(1000));
        }));
    }

    thread::sleep(Duration::from_millis(500)); // wait for creating threads
    let pid = std::process::id() as i32;
    let info = pidinfo::<TaskAllInfo>(pid, 0).unwrap();
    let tids = listpidinfo::<ListThreads>(pid, info.ptinfo.pti_threadnum as usize).unwrap();

    println!("tids from pthread_self: {:?}", ptids.lock().unwrap());
    println!("tids from listpidinfo: {:?}", tids);

    threads.into_iter().for_each(|t| t.join().unwrap());
}

Output:

tids from pthread_self: [4509474304, 123145435578368, 123145439797248, 123145437687808]
tids from listpidinfo: [4509474528, 123145435578592, 123145437688032, 123145439797472]

Any help? @andrewdavidmackenzie

zhongzc avatar Nov 29 '21 09:11 zhongzc

I can have a look tonight.

Can you share details on the OS version you are running it on?

andrewdavidmackenzie avatar Nov 29 '21 10:11 andrewdavidmackenzie

$ uname -a
Darwin zhongzc-mac 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64

zhongzc avatar Nov 29 '21 10:11 zhongzc

I can have a look tonight.

Can you share details on the OS version you are running it on?

keep waiting for your reply

zhongzc avatar Nov 30 '21 03:11 zhongzc

I have taken your code to add a test and play around.

I have pushed to this branch while I do so origin/listpidinfo_fix

There is not much docs available on pthread_self, but I did not in this page:

https://docs.rs/nix/0.9.0/nix/sys/pthread/fn.pthread_self.html

it says

pub fn pthread_self() -> Pthread
Obtain ID of the calling thread (see pthread_self(3)

The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2).

That last line catches my attention and I will try gettid() also

andrewdavidmackenzie avatar Nov 30 '21 09:11 andrewdavidmackenzie

Also, the number of threads is different, so there are obviously deeper differences in these two APIs

/Users/andrew/.cargo/bin/cargo test --color=always --package libproc --lib libproc::proc_pid::test::listpidinfo_listthreads_test --no-fail-fast -- --format=json --exact -Z unstable-options --show-output
Testing started at 5:58 PM ...
    Finished test [unoptimized + debuginfo] target(s) in 0.01s
     Running unittests (target/debug/deps/libproc-acc25a892b0b4854)
Num threads: 5


Left:  [123145317535744, 123145319645184, 123145321754624, 123145323864064]
Right: [4460889824, 123145317535968, 123145319645408, 123145321754848, 123145323864288]
<Click to see difference>

thread 'libproc::proc_pid::test::listpidinfo_listthreads_test' panicked at 'assertion failed: `(left == right)`
  left: `[123145317535744, 123145319645184, 123145321754624, 123145323864064]`,
 right: `[4460889824, 123145317535968, 123145319645408, 123145321754848, 123145323864288]`', src/libproc/proc_pid.rs:745:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:101:14
   2: core::panicking::assert_failed_inner
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:183:17
   3: core::panicking::assert_failed
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:140:5
   4: libproc::libproc::proc_pid::test::listpidinfo_listthreads_test
             at ./src/libproc/proc_pid.rs:745:9
   5: libproc::libproc::proc_pid::test::listpidinfo_listthreads_test::{{closure}}
             at ./src/libproc/proc_pid.rs:719:5
   6: core::ops::function::FnOnce::call_once
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:227:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: test failed, to rerun pass '-p libproc --lib'

Process finished with exit code 101

andrewdavidmackenzie avatar Nov 30 '21 17:11 andrewdavidmackenzie

I haven't found a way to get the equivalent of the gettid() (mentioned in docs in previous comment) id returned as gettid() is only available on Linux.

andrewdavidmackenzie avatar Nov 30 '21 17:11 andrewdavidmackenzie

Any ideas on how we could progress this and try and meet your needs?

andrewdavidmackenzie avatar Feb 08 '23 09:02 andrewdavidmackenzie