How to Pause a Pthread Any Time I Want

How to pause a pthread ANY TIME I want?

If stopping at specific points with a condition variable is insufficient, then you can't do this with pthreads. The pthread interface does not include suspend/resume functionality.

See, for example, answer E.4 here:

The POSIX standard provides no mechanism by which a thread A can suspend the execution of another thread B, without cooperation from B. The only way to implement a suspend/restart mechanism is to have B check periodically some global variable for a suspend request and then suspend itself on a condition variable, which another thread can signal later to restart B.

That FAQ answer goes on to describe a couple of non-standard ways of doing it, one in Solaris and one in LinuxThreads (which is now obsolete; do not confuse it with current threading on Linux); neither of those apply to your situation.

What is the best solution to pause and resume pthreads?

Actually, this code isn't thread safe. The mutex isn't actually protecting anything, leaving the implied predicate vulnerable to race conditions.

Look at this code -- what is the mutex protecting? What protects the suspend/resume state?

void suspendMe()
{
pthread_mutex_lock(&m_SuspendMutex);
pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
}
void resumeMe()
{
pthread_cond_signal(&m_ResumeCond);
pthread_mutex_unlock(&m_SuspendMutex);
}

This is correct:

void suspendMe()
{ // tell the thread to suspend
pthread_mutex_lock(&m_SuspendMutex);
m_SuspendFlag = 1;
pthread_mutex_unlock(&m_SuspendMutex);
}
void resumeMe()
{ // tell the thread to resume
pthread_mutex_lock(&m_SuspendMutex);
m_SuspendFlag = 0;
phtread_cond_broadcast(&m_ResumeCond);
pthread_mutex_unlock(&m_SuspendMutex);
}
void checkSuspend()
{ // if suspended, suspend until resumed
pthread_mutex_lock(&m_SuspendMutex);
while (m_SuspendFlag != 0) pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
pthread_mutex_unlock(&m_SuspendMutex);
}

The thread should call checkSuspend at safe points where it can be suspended. Other threads can call suspendMe and resumeMe to suspend/resume the thread.

Notice that now the mutex protects the m_SuspendFlag variable, ensuring that the thread is told to suspend, told to resume, and checks whether it should suspend or stay suspended under protection, making the code thread-safe.

Would it not be better to use 2 separate mutexes here, or is this the correct way to suspend a pthread??

Using two mutexes would defeat the entire point of condition variables. The whole mechanism by which they work is that you can check whether there is something you should wait for and then atomically wait for it without either holding the lock while you wait or having to release the lock and then wait. If you hold the lock while you wait, how can any other thread change the state? And if you release the lock and then wait, what happens if you miss the change in state?

By the way, it almost never makes sense to pause or resume a thread. If you feel like you need to pause a thread from the outside, that just indicates that you coded the thread to do something you didn't actually want it to do. Questions about pausing or resuming threads often indicate an incorrect mental model of thread programming. A thread might need to wait for something, but it shouldn't be "paused" from the outside because it should already know by its own coding when it shouldn't do some particular bit of work.

How to sleep or pause a PThread in c on Linux

You can use a mutex, condition variable, and a shared flag variable to do this. Let's assume these are defined globally:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int play = 0;

You could structure your playback code like this:

for(;;) { /* Playback loop */
pthread_mutex_lock(&lock);
while(!play) { /* We're paused */
pthread_cond_wait(&cond, &lock); /* Wait for play signal */
}
pthread_mutex_unlock(&lock);
/* Continue playback */
}

Then, to play you can do this:

pthread_mutex_lock(&lock);
play = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

And to pause:

pthread_mutex_lock(&lock);
play = 0;
pthread_mutex_unlock(&lock);

How to pause and resume thread?

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.

How to suspend and resume a POSIX thread in C++?

After a little modification of above code , it seems working . Thanks guy for pointing out issues on above code, the changes are as follow.

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<iostream>
#define on 1
#define off 0
void gpio_write(int fd, int value);
void* led_Flash(void* args);

class PThread {
public:

pthread_t threadID;
volatile int suspended;
int fd;
pthread_mutex_t lock;
PThread(int fd1)
{
this->fd=fd1;
this->suspended =1; //Initial state: suspend blinking untill resume call
pthread_mutex_init(&this->lock,NULL);
pthread_create(&this->threadID, NULL, led_Flash, (void*)this );

}
~PThread()
{
pthread_join(this->threadID , NULL);
pthread_mutex_destroy(&this->lock);
}

void suspendBlink() {
pthread_mutex_lock(&this->lock);
this->suspended = 1;
pthread_mutex_unlock(&this->lock);
}

void resumeBlink() {
pthread_mutex_lock(&this->lock);
this->suspended = 0;
pthread_mutex_unlock(&this->lock);
}
};

void gpio_write(int fd, int value)
{
if(value!=0)
printf("%d: on\n", fd);
else
printf("%d: off\n", fd);
}

void* led_Flash(void* args)
{
PThread* pt= (PThread*) args;
int fd= pt->fd;

while(1)
{
if(!(pt->suspended))
{
gpio_write(fd,on);
usleep(1);
gpio_write(fd,off);
usleep(1);
}
}

return NULL;
}

int main()
{
//Create threads with Initial state: suspend/stop blinking untill resume call
class PThread redLED(1);
class PThread amberLED(2);
class PThread greenLED(3);

// Start blinking
redLED.resumeBlink();
amberLED.resumeBlink();
greenLED.resumeBlink();
sleep(5);

// suspend/stop blinking
amberLED.suspendBlink();

sleep(5);

redLED.suspendBlink();

sleep(5);

amberLED.suspendBlink();

sleep(5);

redLED.resumeBlink();

pthread_exit(NULL);

return 0;
}

C++ pthread_t - How to stop a pthread_t for a period of time

Use pthread_cond_wait (or pthread_cond_timedwait, but probably not) to block the thread. You'll need a predicate -- a variable that holds a value that indicates whether the thread should go or stop. And you'll need a mutex to protect the predicate and condition variable. Another thread can then unblock the thread by taking the mutex, changing the predicate, signalling the condition variable, and releasing the mutex.

However, generally, you just shouldn't do this. If there's something to do, you should let the thread do it. If there's nothing to do, the thread should be coded to either terminate or wait for work. If you have to force this with specific code, it's likely that you're doing something wrong in the first place.

The thread should be coded to do all, and only, what you want it to do. You shouldn't need to "push it around" from the outside except in truly unusual situations.

In C++, how to pause and resume a thread from outside?

@freakish said it can be done with pthread and signals, but no portable way.

In Windows, I just found SuspendThread(t.native_handle()) and ResumeThread(t.native_handle()) (where t is of type std::thread) are available. These would solve my problem.



Related Topics



Leave a reply



Submit