代码之家  ›  专栏  ›  技术社区  ›  SK17

如何在C++中暂停和恢复POSIX线程?

  •  0
  • SK17  · 技术社区  · 8 年前

    当我突然知道创建和终止线程时 每次使用pthread_kill()都不是一个好方法,所以我要 对于使用 thread1.suspend() thread1.resume() ,无论何时需要。如何做/实施?

    以下LED闪烁代码仅供参考。期间 thread1.start() 创建线程 suspended = false; 因为它陷入了一个暂时的循环,所以仍在继续。 调用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 回复  |  直到 8 年前
        1
  •  0
  •   SK17    8 年前

    在对上面的代码稍加修改之后,它似乎可以工作了。感谢Guy指出上述代码中的问题,更改如下。

    #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;
    }