Linux: detect at runtime that a process have multiple threads
Asked Answered
S

5

7

I'm asking about linux with recent glibc.

Is there a way to detect that process consist of 1 thread or of several threads?

Threads can be created by pthread, or bare clone(), so I need something rather universal.

UPD: I want to detect threads of current process from it itself.

Steele answered 8/11, 2010 at 16:38 Comment(4)
Within your own program or externally?Pestilence
I have to ask: why don't you already know? Is a library or such opening them under the covers?Pestilence
Duck, this code will be placed in .so library, which can be linked in various programs, both with pthread-based or clone-based threads.Steele
I think if your library depends on knowing this, it won't be robust. There might be only one thread just now, but another one starting very soon. How often do you plan to check?Butterfat
A
11

Check if directory /proc/YOUR_PID/task/ contains only one subdirectory. If you have more than one thread in process there will be several subdirs.

The hardlink count can be used to count the subdirectories. This function returns the current number of threads:

#include <sys/stat.h>

int n_threads(void)
{
    struct stat task_stat;

    if (stat("/proc/self/task", &task_stat))
        return -1;

    return task_stat.st_nlink - 2;
}
Avalos answered 8/11, 2010 at 17:9 Comment(9)
Hmm... Yes. There are threads for some processes. But to get information from /proc I need a lot of syscalls: opendir/readdir. Is there some easier way?Steele
@osgx: You can do it with one syscall - just stat("/proc/self/task") and check if st_nlink > 3.Conspicuous
caf, Thanks, but does the procfs maintain inode link count for dirs? Do you check this method?Steele
@caf, on my system the stat of proc/self/task returns 3 nr_links instead of 4 if I dont do a ls /proc/self/task or ps axm before stat...Steele
@osgx: Works fine for me on kernel 2.6.32 - are you sure you don't have a race condition?Conspicuous
@caf, what kind of race?? tested on long-running 2 thread test, both stat from the test itself and externally with stat/ls/ps utilities.Steele
@osgx: A race as in the stat() happening before the second thread starts or after the second thread finishes.Conspicuous
@caf, the stat is done in the thread itself. In both threads, after the _create. The stat CLI utility shows the same (after printf from second thread and waiting a some time - multiple stat runs shows nlink=3; then do a ls /proc/pid/task and all stats will show nlink=4). The interesting thing is that after second thread exit (and pthread_join) - if I use a ls while 2 threads running, stat(2) from program still shows nlink=4.Steele
@osgx: What kernel version? It's possible that the kernel behaviour changed at some point.Conspicuous
K
0

I suppose you could run 'ps' (via popen() or similar) and parse its output, and see how many times your process's ID (as returned by getpid()) appears in the output. There might be a better way, but that is what first comes to mind.

Kappel answered 8/11, 2010 at 17:15 Comment(1)
NO, please, no any subprocess starting :). It is so slow, and I need a fast way, like 1 syscall or some flag reading or so..Steele
P
0

/proc is the standard way to do this in Linux. Tools like 'ps' work through /proc. In Linux 2.6, you can find the number of threads in /proc/self/stat, but that is not backwards compatible.

Probably answered 8/11, 2010 at 17:30 Comment(0)
C
0

The answer from Victor is certainly the fastest, although you may want to consider using the ps library instead.

The name under Ubuntu is libprocps3-dev so you use install it using:

sudo apt-get install libprocps3-dev

The headers are found under /usr/include/proc.

Note that the library works by reading /proc. So it is the same as reading the files of interest directly, only it will know of differences between various versions and take care of that under the hood for you.

See http://procps.sourceforge.net/index.html for details.

Crinoline answered 1/6, 2015 at 7:9 Comment(2)
How much system calls will do procps to answer the question "process consist of 1 thread or of more than 1 thread"?Steele
On the main answer, I see that many people ask about the compatibility problem. procps is definitely slow, but should work transparently on newer and older versions of Linux. It depends whether you need speed or long term compatibility.Crinoline
E
0

A bit of an alternative way that hasn't been mentioned, but is definitely the most hassle-free:

int ret = unshare(CLONE_THREAD); // CLONE_SIGHAND and/or CLONE_VM also works
if (ret && errno == EINVAL) {
    // we are multi-threaded
}

For single-threaded programs, this is a no-op. This won't allow you to see the amount of created threads, but that wasn't asked.

Source: unshare man page:

In addition, CLONE_THREAD, CLONE_SIGHAND, and CLONE_VM can be specified in flags if the caller is single threaded (i.e., it is not sharing its address space with another process or thread). In this case, these flags have no effect. [...] If the process is multithreaded, then the use of these flags results in an error.

Edit: from your comments, it seems like this might be what you are looking for. It's a single system call and doesn't start any other processes.

Errhine answered 3/4, 2023 at 12:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.