zoukankan      html  css  js  c++  java
  • posix多线程--条件变量

    条件变量是用来通知共享数据状态信息的。

    1.条件变量初始化两种方式:
    (1)静态初始化
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    代码示例如下:

    #include <pthread.h>
    typedef struct my_struct_tag {
        pthread_mutex_t     mutex;  /* Protects access to value */
        pthread_cond_t      cond;   /* Signals change to value */
        int                 value;  /* Access protected by mutex */
    } my_struct_t;
    
    my_struct_t data = {
        PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
    
    int main (int argc, char *argv[])
    {
        return 0;
    }

    (2)动态初始化
    int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *condattr);
    int pthread_cond_destroy(pthread_cond_t *cond);
    代码示例如下:

    #include <pthread.h>
    
    typedef struct my_struct_tag {
        pthread_mutex_t     mutex;  /* Protects access to value */
        pthread_cond_t      cond;   /* Signals change to value */
        int                 value;  /* Access protected by mutex */
    } my_struct_t;
    
    int main (int argc, char *argv[])
    {
        my_struct_t *data;
        int status;
        data = malloc (sizeof (my_struct_t));
        status = pthread_mutex_init (&data->mutex, NULL);
        status = pthread_cond_init (&data->cond, NULL);
        status = pthread_cond_destroy (&data->cond);
        status = pthread_mutex_destroy (&data->mutex);
        (void)free (data);
        return status;
    }

    2.等待条件变量
    int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
    int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,struct timespec *expiration);
    当线程等待条件变量时,它必须将相关互斥量锁住。在阻塞线程之前,条件变量等待操作将解锁互斥量,而在重新返回线程之前,会再次锁住互斥量。

    3.唤醒条件变量
    int pthread_cond_signal(pthread_cond_t *cond);
    int pthread_cond_broadcast(pthread_cond_t *cond);
    在发送信号时也必须锁住互斥量,如果互斥量不被锁住,任何线程可以在被唤醒线程之前锁住互斥量。这将是一个产生被拦截唤醒的根源。例如,一个低优先级的线程可能锁住了互斥量,使高优先级的线程无法被其他线程唤醒,延迟了高优先级线程的调度。

    4.需要在等待条件变量线程被唤醒后,检测条件
    (1)被拦截的唤醒:等待条件变量被唤醒并加锁相关互斥量,若一个其他线程获得了互斥量,它可能在等待之前先检查条件。由于条件为真,所以它不需等待,直接处理工作,当它解锁时,已经没有可做的工作了。我们的第一个等待条件变量线程加锁互斥量后,再次检测条件,很有必要。
    (2)松散的条件:使用不确定的条件时,循环检测条件,代码会更加健壮。
    (3)假唤醒:在某些多处理器系统,会发生假唤醒的情况。

    5.使用示例

    主线程等待条件信号2S,子线程睡眠1S,改变共享数据值,发送信号,主线程接收信号,继续运行。

    #include<stdio.h>
    #include<pthread.h>
    #include<errno.h>                                                                
    typedef struct cond_tag
    {
            pthread_mutex_t mutex;
            pthread_cond_t cond;
            int valid;
    }cond_t;
    cond_t data = {
            PTHREAD_MUTEX_INITIALIZER,
            PTHREAD_COND_INITIALIZER,
            0
    };
    void *thread_route(void *arg)
    {
            sleep(1);
            pthread_mutex_lock(&data.mutex);
            data.valid = 1;
            pthread_cond_signal(&data.cond);
            pthread_mutex_unlock(&data.mutex);
            return NULL;
    }
    int main(void)
    {
            int status;
            pthread_t pid;
            pthread_create(&pid,NULL,thread_route,NULL);
            struct timespec timeout;
            timeout.tv_sec = time(NULL)+2;
            timeout.tv_nsec = 0;
            pthread_mutex_lock(&data.mutex);
            while(data.valid==0)
            {
                    status = pthread_cond_timedwait(&data.cond,&data.mutex,&timeout);
                    if(status==ETIMEDOUT)
                    {
                            printf("wait timed out
    ");
                            break;
                    }
            }
            if(data.valid==1)
            {
                    printf("cond is signaled
    ");
            }
            pthread_mutex_unlock(&data.mutex);
            
            return 0;
    }  

    参考资料:《POSIX多线程程序设计》 pp.59-74

  • 相关阅读:
    系统UINavigationController使用相关参考
    iOS工程集成支付宝错误Undefined symbols for architecture armv7
    Xcode工程使用CocoaPods管理第三方库新建工程时出现错误
    Xcode报错:“Your build settings specify a provisioning profile with the UUID..... however, no such provisioning profile was found”
    iOS开发问题之Could not instantiate class named NSLayoutConstraint
    UICollectionView使用相关博文链接
    UIRefreshControl的使用
    iOS沙盒路径的查看和使用
    【汇总】涉及iOS&iPhone开发相关文章汇总
    【汇总】iOS开发及Xcode使用中遇到的一些报错问题汇总
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/5386366.html
Copyright © 2011-2022 走看看