0

Let's say we have the parent thread Tp which starts two child threads Tc1 and Tc2 in the same order and waits for Tc2 to join (Tc2.join()).

Tc2: It starts and waits for the user input by invoking a shell. Tc1: It starts and runs a time counter and after a specified time if no input is given by the user in Tc2 child thread, it stops the shell started by the Tc2.

Now the problem is that the parent thread remains in waiting state for Tc2 to join and the process remains hanged.

How can Tc1 terminate the Tc2 (which is in user input waiting state) so that parent thread Tp can continue?

Browsed a lot but could not get the break through.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Dilip
  • 7
  • 6
  • Terminating threads is a surefire way of deadlocking your process sooner or later. You need to rethink your approach. What is behind "invoking a shell": is this an external process or a loop that reads from `std::cin` ? – Botje Oct 08 '20 at 09:53
  • using "readline" for reading user input. – Dilip Oct 08 '20 at 09:57
  • @Tony: my use case is to monitor if the session is idle i.e. no user input for a certain interval, then continue to shutdown the session in the main thread Tp. – Dilip Oct 08 '20 at 10:17
  • Ah, so this is an XY problem! See [how to make readline timeout](https://stackoverflow.com/questions/31181148/how-to-make-readline-timeout), as well as the `select` recommendation in my other comment. Next time, please give us more context up front so we can better help you. – Botje Oct 08 '20 at 10:54
  • Now that I've skimmed the readline documentation, you could also set `rl_done`, or just send a `SIGINT` signal to the Tc2 thread. – Botje Oct 08 '20 at 11:00
  • rl_done would be effective on the immediate next iteration (which is already implemented), but the issue is it waits for user manual intervention i.e. pressing any key or enter. Similar to what is mentioned in force-exit-from-readline-function query. – Dilip Oct 08 '20 at 14:43
  • how to send SIGINT to Tc2 from Tc1? – Dilip Oct 08 '20 at 14:45
  • Did you also check the other question I linked? (how to make readline timeout) – Botje Oct 08 '20 at 15:47
  • This requirement can be achieved by just calling pthread_cancel(Tc2 thread id) from Tc1. – Dilip Oct 09 '20 at 10:24

1 Answers1

2

Although some Operating Systems allow violent termination of threads, this is almost always a bad idea. This is because threads share memory and you have no idea what a thread is doing at the moment of termination. There is a good chance of deadlock, memory-leaks and crashes.

What you do need is a way to ask a thread to terminate itself when convenient. The simplest pattern is for a thread to poll an atomic isRunning variable. A more complex pattern will involve using poll to wait in multiple file descriptors. One of which can be an eventdfd or a simple signalling pipe. When you want the thread to shut down, you signal the thread and it then shuts itself down.

doron
  • 27,972
  • 12
  • 65
  • 103
  • Doing more or less similar thing, but as mentioned above issue is Tc2 is in the waiting state for user input and parent thread Tp is waiting for Tc2 to join. – Dilip Oct 08 '20 at 14:49
  • Use poll on stdin then use read to get the keystrokes. – doron Oct 08 '20 at 16:52