zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
    
  • 相关阅读:
    ORACLE时间函数(SYSDATE)简析
    RestTemplate请求
    Java中ASM框架详解
    java进阶
    Java,Mysql-根据一个给定经纬度的点,进行附近500米地点查询–合理利用算法
    JAVA程序员必看的15本书-JAVA自学书籍推荐
    Linux curl命令详解
    Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
    腾讯信鸽推送Android SDK快速指南
    信鸽推送.NET SDK 开源
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/14697506.html
Copyright © 2011-2022 走看看