• muduo 库解析之九:Condition


    Condition Variable

    初始化和销毁

    #include <pthread.h>
    
    int pthread_cond_destroy(pthread_cond_t *cond);
    int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
    
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER
    
    • pthread_cond_init函数初始化一个Condition Variable,attr参数为NULL则表示缺省属性。
    • pthread_cond_destroy函数销毁一个Condition Variable。
    • 如果Condition Variable是静态分配的,也可以用宏定义PTHEAD_COND_INITIALIZER初始化,相当于用pthread_cond_init函数初始化并且attr参数为NULL
    • 成功返回0,失败返回错误号。

    等待和通知

    #include <pthread.h>
    
    int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct 	timespec *restrict abstime);
    int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
    
    int pthread_cond_broadcast(pthread_cond_t *cond);
    int pthread_cond_signal(pthread_cond_t *cond);
    
    • 一个Condition Variable总是和一个Mutex搭配使用的。一个线程可以调用pthread_cond_wait在一个Condition Variable上阻塞等待,这个函数做以下三步操作:
      • 释放Mutex。
      • 阻塞等待。
      • 当被唤醒时,重新获得Mutex并返回。
    • pthread_cond_timedwait函数还有一个额外的参数可以设定等待超时,如果到达了abstime所指定的时刻仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT
    • 一个线程可以调用pthread_cond_signal唤醒在某个Condition Variable上等待的另一个线程。
    • 调用pthread_cond_broadcast唤醒在这个Condition Variable上等待的所有线程。

    源码

    Condition.h

    #pragma once
    
    #include "Mutex.h"
    #include  <pthread.h>
    
    namespace muduo
    {
        class Condition
        {
        public:
            Condition(MutexLock& mutex) : mutex_(mutex)
            {
                MCHECK(pthread_cond_init(&pcond_,NULL));
            }
    
            ~Condition()
            {
                MCHECK(pthread_cond_destroy(&pcond_));
            }
    
            void wait()
            {
                //@ pthread_cond_wait will release mutex
                MutexLock::UnassignGuard ug(mutex_);
                MCHECK(pthread_cond_wait(&pcond_, mutex_.get_mutex()));
            }
    
            //@ returns true if time out, false otherwise.
            bool wait_for_seconds(double seconds);
    
            void notify()
            {
                MCHECK(pthread_cond_signal(&pcond_));
            }
    
            void notify_all()
            {
                MCHECK(pthread_cond_broadcast(&pcond_));
            }
    
        private:
            MutexLock& mutex_;
            pthread_cond_t pcond_;
        };
    }
    

    Condition.cc

    #include "Condition.h"
    
    namespace muduo
    {
    
        //@ returns true if time out, false otherwise.
        bool Condition::wait_for_seconds(double seconds)
        {
            struct timespec abs_time;
            clock_gettime(CLOCK_REALTIME,&abs_time);
            const int64_t kNanoSecondsPerSecond = 1000000000;
            int64_t nano_seconds = static_cast<int64_t>(seconds * kNanoSecondsPerSecond);
    
            abs_time.tv_sec += static_cast<time_t>((abs_time.tv_sec + nano_seconds) / kNanoSecondsPerSecond);
            abs_time.tv_nsec += static_cast<long>((abs_time.tv_sec + nano_seconds) % kNanoSecondsPerSecond);
    
            MutexLock::UnassignGuard ug(mutex_);
            return ETIMEDOUT == pthread_cond_timedwait(&pcond_,mutex_.get_mutex(),&abs_time);
        }
    }
    
    
  • 相关阅读:
    C语言关键字register、extern、static、一些总结,及项目中使用的心得
    c语言,文件操作总结
    《Redis内存数据库》Redis内存数据库技术总结
    《Redis内存数据库》Redis环境搭建(Linux)
    《Linux 操作系统》Linux的常用命令操作大全
    《Java练习题》Java编程题合集(全)
    《Java练习题》Java习题集一
    《Java基础知识》Java技术总结
    《Java基础知识》Java数据类型以及变量的定义
    《Java 底层原理》Jvm 类的加载原理
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/14697506.html
Copyright © 2020-2023  润新知