Как приостановить и возобновить поток POSIX в C ++? - PullRequest
0 голосов
/ 12 июня 2018

Как я узнал, создание и прерывание потока с помощью pthread_kill () каждый раз не очень хороший способ, поэтому я использую метод приостановки и возобновления для потока, использующего thread1.suspend() и thread1.resume(), когда это необходимо.Как это сделать / реализовать?

Взять ниже мигающий светодиодный код для справки.Во время thread1.start() создание потока с suspended = false; продолжается, так как он застрял в цикле while.Вызов thread1.suspend () не имеет никакого эффекта.

#define on 1
#define off 0
void gpio_write(int fd, int value);
void* led_Flash(void* args);


class PThread {
    public:

    pthread_t threadID;
    bool suspended;
    int fd;
    pthread_mutex_t m_SuspendMutex;
    pthread_cond_t m_ResumeCond;

    void start() {
        suspended = false;
        pthread_create(&threadID, NULL, led_Flash, (void*)this );
    }

    PThread(int fd1) { this->fd=fd1; }
    ~PThread() { }

    void suspend() {
        pthread_mutex_lock(&m_SuspendMutex);
        suspended = true;
        printf("suspended\n");
        do {
            pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
        } while (suspended);
        pthread_mutex_unlock(&m_SuspendMutex);
    }

    void resume() {
        /* The shared state 'suspended' must be updated with the mutex held. */
        pthread_mutex_lock(&m_SuspendMutex);
        suspended = false;
        printf("Resumed\n");
        pthread_cond_signal(&m_ResumeCond);
        pthread_mutex_unlock(&m_SuspendMutex);
    }
};

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

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


return NULL;
}


int main()
{
    int fd1=1,fd2=2, fd3=3;

    class PThread redLED(fd1);
    class PThread amberLED(fd2);
    class PThread greenLED(fd3);

    redLED.start();
    amberLED.start();
    greenLED.start();

    sleep(1);
    redLED.suspend();

return 0;
}

Может ли какой-нибудь орган помочь мне, пожалуйста?

1 Ответ

0 голосов
/ 13 июня 2018

После небольшой модификации кода выше, похоже, работает.Спасибо, парень, за указание на проблемы в приведенном выше коде, изменения следующие:

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...