分享

慎用进程间条件变量pthread

 astrotycoon 2015-01-28

条件变量是用于多线程/多进程间同步,是一种典型的睡眠唤醒用法。P1等待某个事件的发生,P2触发事件,唤醒P1。

条件变量在初始化时,可以通过接口pthread_condattr_setpshared指定该条件变量可用于进程内的线程间同步,还是用于进程间同步。

但是,在linux的glibc实现中,进程间同步却存在着一个缺陷。将导致问题扩散,非常严重。原因如下:

pthread_cond_t结构体是一个复杂的数据结构,包含了等待信息,多个进程都可能同时调用等待函数pthread_cond_wait/pthread_cond_timedwait,

唤醒函数pthread_cond_signal/pthread_cond_broadcast,为了防止一个或者多个等待者、唤醒者同时操作pthread_cond_t的成员,必须进行互斥.。

所以,pthread_cond_t里还有一个锁。接口实现上,pthread_cond_wait/pthread_cond_timedwait,pthread_cond_signal/pthread_cond_broadcast

都必须先获取锁,然后操作数据,完毕释放锁。

在多进程上,如果某个进程在pthread_cond_xxx的接口里获取了锁以后,因某种原因退出了(比如某个线程运行异常了)。

那么,悲剧来了,锁没有释放。于是,其他的进程只要调用到这个条件变量的接口,将因为获取不到锁而等待,且一直等待下去。

一个进程的异常导致所有进程的异常。

令人困惑的是,mutex也可用于进程间互斥,pthread_mutex_setpshared设置。但是pthread_mutex_t却支持这种场景,进程获取到了mutex后复位了,

没有释放锁,OS帮忙释放(需要在mutex初始化时设置pthread_mutexattr_setrobust_np)。

同样可用于进程间的条件变量为什么没有这个机制?

难道这就是大教堂与大集市的区别。大集市下各种实现,没有一种统一的策略或者机制,保证对外呈现的一致性?


条件变量另外一个让人困惑或者说问题的地方是 这个超时等待接口pthread_cond_timedwait。

通过该接口调用者可以指定一段超时时间,如果超时时间内没有被唤醒则返回,表示这段时间内条件不满足。

但问题是,pthread_cond_timedwait里面获取锁的时间并没有超时。

如果pthread_cond_timedwait接口里获取锁的时间超过了传入的超时时间,那么,返回给调用者的超时时间是不准的,而且难以评估。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多