zoukankan      html  css  js  c++  java
  • Linux线程唤醒与等待

    生产者消费者模式在程序设计中出现频率非常高,经常会有线程间通过消息队列或其他共享变量进行交互的场景。而这时就会出现一个问题,消费者如何知道生产者已经生产了数据呢?有的程序会采取消费者循环判断消息队列大小是否为0,如果不为0则取出数据之类的方法。但是该种方法带来两个问题:

    1. 生产者产出数据到消费者获得数据的延时较大。

    2. CPU占用较高。

    如果需要降低延时,则必然要提高轮询的频率,那么CPU占用就会升高。反之亦然,两者无法同时解决。

    于是,唤醒等待机制就成为适合该种场景的解决方案。

    该机制需要一个互斥对象以及条件变量共同完成,如下:

    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t mutex;

    其中条件变量使用宏结构常量进行赋值。接下来进行互斥对象与条件变量的初始化:

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    生产者唤醒逻辑:

    pthread_mutex_lock(&mutex);  
    pthread_cond_signal(&cond);   
    pthread_mutex_unlock(&mutex);

    消费者等待逻辑:

    pthread_mutex_lock(&mutex);  
    pthread_cond_wait(&cond, &mutex);  
    pthread_mutex_unlock(&mutex);

    看到这里可能会有点疑问,为何除了条件变量还需要一个互斥对象呢?等待时为什么需要条件变量和互斥对象共同生效呢?

    条件变量的操作也需要达到线程安全的要求,因此需要互斥对象来进行保证。避免两个线程同时操作条件变量引发问题。而通过查阅pthread_cond_wait()的相关资料可知,当程序运行到pthread_cond_wait()时,会将互斥对象锁释放,以便生产者能够顺利唤醒。而在消费者被成功唤醒,pthread_cond_wait()等待完成后,互斥对象会被重新上锁直到手动释放。

    下方提供完整的DEMO以供参考:

    /* test.cpp */
    
    #include <pthread.h>
    #include <iostream>
    #include <signal.h>
    #include <stdlib.h>  
    #include <unistd.h>  
    
    using namespace std;
    
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t mutex;
    
    void *ThreadFunc(void *arg) {  
      
      pthread_mutex_lock(&mutex);  
      /*此处等待唤醒*/
      cout << "Thread sleeping..." << endl;
      pthread_cond_wait(&cond, &mutex);  
      /*唤醒成功*/    
      cout << "Thread awakened!" << endl;
      pthread_mutex_unlock(&mutex);
    
      return NULL;
    }
    
    int main(void) {
    
      pthread_mutex_init(&mutex, NULL);
      pthread_cond_init(&cond, NULL);
    
      pthread_t tid;
      pthread_create(&tid, NULL, ThreadFunc, NULL);  
    
      /*等待5秒再唤醒,方便观察*/
      usleep(5000000);
    
      pthread_mutex_lock(&mutex);  
      /*唤醒*/
      pthread_cond_signal(&cond);   
      pthread_mutex_unlock(&mutex);
    
      return 0;
    }

    附上操作命令:

    g++ test.cpp -o test -pthread
    ./test
  • 相关阅读:
    linux时间设置相关
    tcp/ip协议和http协议
    redis和memcache的比较
    How to Display Image In Picturebox in VC++ from Iplimage and Mat
    关于技术与业务的理解
    怎样写出好代码——设计原则
    怎么写出好代码——坏味道
    linux 用户管理
    浅谈ajax
    浅析闭包和内存泄露的问题
  • 原文地址:https://www.cnblogs.com/xuzichao/p/11585191.html
Copyright © 2011-2022 走看看