0

There is a way to look when pid/tid status change with waitpid but this is blocking function.

I want to monitor all threads in specific pid and get signal when one of them change and print the tid.

For now I open threads as count of threads in that process and each 1 make waitpid on 1 tid and after that blocking function finish I print that tid that changed.

How can I get a signal that tid change so I can monitor all tid's in 1 thread.

I didn't want to monitor all pid in system only specific pid/tid.

Those tids/pids are not children of my process.

paramikoooo
  • 177
  • 2
  • 16

2 Answers2

0

You can call

int status;
pid_t waitpid(-1, &status, 0);

to wait for any child process change. So you do not have to specify in advance, which pid to monitor, and can react on any status change. This way you do not need to start one thread for each pid.

As to the signal part of your question: A SIGCHLD is sent to your process when a child process exits. This signal is ignored by default, but you can install a custom signal handler for it, of course.

If you only want to reap specific pids, linux provides the option WNOWAIT, which only reports the state, but does not really reap the child process. Now you can check, if the pid is one of those you want to monitor, and if so, call waitpid() again without the option.

If the processes are not children, waitpid() cannot be used in general. One option is, to attach with ptrace() to these 40 processes to get signalled, if one of these processes exit. This might have unwanted side-effects, however.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • I sorry , I edit the post, what I mean is to monitor all tid's status change in specific pid – paramikoooo Feb 13 '20 at 09:02
  • @paramikoooo `waitpid()` does not work at all for non-child processes. There is one (a bit hacky) option however, see above. – Ctx Feb 13 '20 at 09:02
  • @paramikoooo If you pass `-1` as the pid to wait for, you wait for all *child* processes, not "all" processes. And even with `SIGCHLD` you'll get signals for all child processes as well. – Some programmer dude Feb 13 '20 at 09:03
  • @Ctx , ok I using `ptrace` to attach to each of that tid's, and then how can I get signal when one of them changed without blocking? – paramikoooo Feb 13 '20 at 09:09
  • @paramikoooo Just install a SIGCHLD handler, that should be called on tracee exit – Ctx Feb 13 '20 at 09:09
  • @Someprogrammerdude Of course child processes, I presumed that this is clear... – Ctx Feb 13 '20 at 09:10
  • @Ctx thank you so much about all , so do I need to install a SIGCHLD handler ,and then use `PTRACE_ATTACH` (without `waitpid ` ) to attach the tid and then I will get signal to handler function when the tid chaged? will I get the thread number to that handler ? – paramikoooo Feb 13 '20 at 09:12
  • @paramikoooo Indeed I have not tested this with individual threads, but it _should_ work ,because _strace_ on threads works, too. If you install the signal handler with `sigaction()` and `SA_SIGINFO`, then you get a siginfo-structure containing the pid. – Ctx Feb 13 '20 at 09:14
  • @Ctx The problem is that the question mentions *threads* not processes. – Some programmer dude Feb 13 '20 at 09:16
  • @Someprogrammerdude As I said, it should work with threads (watching them with `ptrace()` for exit) – Ctx Feb 13 '20 at 09:17
0

If you're using POSIX threads, then you could use pthread_cleanup_push and pthread_cleanup_pop to call a "cleanup" function when your thread is exiting.

This "cleanup" function could then send one of the user signals (SIGUSR1 or SIGUSR2) to the process which then catches it and treats it as a signal about thread termination.

If you use sigqueue you can add the thread-id for the signal handler so it knows which thread just exited.

You can use pthread_sigmask to block the user signal in all threads, to make sure it's only delivered to the main process thread (or use pthread_sigqueue to send to the main process thread specifically).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621