zoukankan      html  css  js  c++  java
  • Condition Variable使用及其Thread Cancellation线程取消

    条件变量Condition Variable的一般用法:

    唤醒用法:

     1 struct {
     2     pthread_mutex_t mutex;
     3     pthread_cond_t cond;
     4     //whatever variables maintain the condition
     5 ) var = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, ... };//声明结构体并初始化
     6   
     7 pthread_mutex_lock(&var.mutex);
     8 //set condition true
     9 pthread_cond_signal(&var.cond):
    10 pthread_mutex_unlock(&var.mutex);

    等待用法:

    1 pthread_mutex_lock(&var.mutex);
    2 while (/*condition is false*/)
    3   pthread_cond_wait(&var.cond, &var.mutex);
    4 //modify condition
    5 pthread_mutex_unlock(&var.mutex);

    避免锁冲突:

    有一种情况是,唤醒线程中调用pthread_cond_signal之后,假如立即调度等待线程。那么等待线程立即运行然后停止,因为它不能获取到锁。为了不影响等待线程及时获取锁,唤醒线程另一种写法是:

    1 int dosignal;
    2 pthread_mutex_lock(&nready.mutex);
    3 dosignal = (nready.nready == 0);
    4 nready.nready++;
    5 pthread_mutex_unlock(&nready.mutex);
    6 
    7 //先释放锁,然后唤醒等待线程
    8 if (dosignal)
    9     pthread_cond_signal(&nready.cond);

    即,先释放锁,然后唤醒。这样就避免了等待线程请求锁的冲突问题。而调用pthread_cond_wait之前必须加锁。

    条件变量的线程取消(Thread Cancellation)问题:

    在使用条件变量进行等待时,注意线程被取消时的锁释放问题。为了让线程退出时释放所持有的锁,可以设置pthread_cleanup_push清理函数,参数是清理函数及其参数,这些清理函数在线程被取消时或正常退出时(不管是pthread_exit还是从线程执行函数返回)都会被执行。使用pthread_cleanup_pop弹出清理函数栈顶的函数,参数非0表示执行,0表示不执行。

    程序正常执行时,条件变量的wait函数正常返回,所以,pthread_cleanup_pop(0)表示,取消函数不会被执行;当程序在wait中被取消时,程序不会从wait函数返回,而是重新获取条件变量关联的锁之后,直接退出,但是退出之前调用清理函数。

    一般用法:

     1 pthread_mutex_lock(&var.mutex); 2 while (/*condition is false*/)
     3 {
     4     pthread_cleanup_push(/*cancel_handler*/,/*arg*/);
     5     //pthread_cond_wait是取消点,被取消时,函数不会返回,但是会重新获取条件变量关联的锁,即var.mutex。因为该函数内部实现机制就是先释放锁然后等待,等待结束再原子操作重新获取锁。
     6    pthread_cond_wait(&var.cond, &var.mutex);
     7     pthread_cleanup_pop(0);
     8 }
     9 //modify condition
    10 pthread_mutex_unlock(&var.mutex);

    在清理函数中如cancel_handler,释放条件变量关联的锁即可。

    1 void cancel_handler(void *arg)
    2 {
    3     var = arg;
    4     //该函数将相关对象恢复至被cancel之前的状态
    5   
    6     //其他操作
    7     pthread_mutex_unlock(&var.mutex);      
    8 }
  • 相关阅读:
    HTTP状态码
    Hibernate的配置与简单使用
    Java基础学习总结 -- 多线程的实现
    MySQL学习笔记 -- 数据表的基本操作
    Java基础学习 -- I/O系统、流
    理解文件的编码
    Java基础学习 -- 异常
    Java基础学习 -- GUI之 事件处理基础
    Java基础学习总结 -- 图形用户界面GUI
    Java基础学习 -- 接口
  • 原文地址:https://www.cnblogs.com/NerdWill/p/5003570.html
Copyright © 2011-2022 走看看