3

I am trying to write the program, which will stop and continue thread instead of cancel it. I need to know, how can I achieve that?

I want to use pthread_kill() function with SIGSTOP and SIGCONT signals to thread.

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <time.h>



void *threadfunc(){
        while(1){
            printf("i am thread \n");
            sleep(1);
        }
}

void main(){
    pthread_t thread;
    pthread_create(&thread, NULL, threadfunc, NULL);
    sleep(2);
    pthread_kill(thread, SIGSTOP);
    printf("signal sent \n");
    sleep(2);
    printf("i am main thread \n");
}

My expectation: Program starts, 2 times "i am thread" printed, pthread_kill sent signal to stop the thread, user see "signal sent" and "i am main thread". Actual results: Programs starts, 2 times "i am thread" printed, pthread_kill sent stop signal and program terminate

Max
  • 35
  • 4

2 Answers2

4

There is no one right way to pause and resume a thread.

First, there is no way at all to do it without the cooperation of the code that thread is running. Otherwise, disaster could occur if you pause a thread while it holds a lock that the thread that would resume it needs to acquire before it can resume. So you must have the cooperation of the code the thread you want to pause is running.

With the thread's cooperation, you can do it however you like. You can have an atomic bool that the thread periodically checks. You can just not give the thread work to do if it's designed to pause when it has no work to do.

There's no one right way and it entirely depends on other design decisions. Primarily, it depends on what that code is doing and why you want to pause it.

One other thing that is extremely important: Any time you feel you need to reach into a thread from outside and make it do or not do something, that should be a sign to you that you coded the thread wrong in the first place. A thread should know what work it needs to do and when it needs to not do work by its own design. If something else has to "reach in" intrusively and make it do or not do things, you should re-examine the design decisions that got you to that point.

And to your specific point:

I want to use pthread_kill() function with SIGSTOP and SIGCONT signals to thread.

That couldn't possibly work. What if the thread happens to hold an internal library lock that needs to be acquired to return from pthread_kill? The thread trying to pause it would also pause itself. In any event, SIGSTOP is defined as stopping a process, not a thread.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

You cannot use SIGSTOP/SIGCONT signals on threads as they have several major problems:

  • They are actualy handled by process, not by thread. Even when sent to thread.
  • They don't get queued. If you send them faster than handler can receive them, only the first one gets handled. So you can pause thread, loose unpause signal and remain deadlocked because of it.

Luckily there are "realtime signals", which can be used to emulate STOP/CONT behaviour you are looking for. See my proposal here: https://stackoverflow.com/a/68119116/10277365

Harvie.CZ
  • 73
  • 1
  • 9
  • ⁺¹, I confirm that STOP signal acts on the process rather than a thread. In terms of experiments I was trying to `SIGSTOP` one of many threads of a Firefox process, but that was always resulting in the complete process being paused, no matter what thread the signal went to. – Hi-Angel Oct 23 '22 at 14:28