互斥量与读写锁操作函数ITeye - 威尼斯人

互斥量与读写锁操作函数ITeye

2019年03月28日10时22分48秒 | 作者: 浩轩 | 标签: 互斥,函数,读写 | 浏览: 448

  互斥变量是用 pthread_mutex_t 数据类型表明的。下面几个函数可操作互斥量。
#include pthread.h 
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
 const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
 /* 一切函数的回来值:若成功,回来 0;不然,回来过错编号 */

  运用互斥量前有必要先对它进行初始化,可把它设置为常量 PTHREAD_MUTEX_INITIALIZER(只适用于静态分配的互斥量),也能够经过 pthread_mutex_init 函数进行初始化。要用默许的特点初始化互斥量,只需把 pthread_mutex_init 的参数 attr 设为 NULL。假如互斥量是动态分配的,则开释内存前需求调用 pthread_mutex_destroy。
  函数 pthread_mutex_lock 和 pthread_mutex_unlock 可别离对互斥量进行加锁和解锁。假如互斥量现已上锁,调用线程将堵塞直到互斥量被解锁。假如线程不期望被堵塞,能够运用 pthread_mutex_trylock 测验对互斥量加锁。若调用 pthread_mutex_trylock 时互斥量未上锁,则该函数就锁住互斥量,然后直接回来 0,不然该函数就会失利,然后回来 EBUSY。
  下面这段代码描绘了如何用互斥量来维护某个数据结构。当有多个线程要拜访动态分配的目标时,能够在目标中嵌入引证计数,保证在一切运用该目标的线程完结数据拜访之前,该目标的内存空间不会被开释。
#include stdlib.h 
#include pthread.h 
struct foo{
 int f_id;
 int f_count;
 pthread_mutex_t f_lock;
 /*...more stuff here...*/
struct foo* foo_alloc(int id){ // allocate the object
 struct foo *foop;
 if((foop=molloc(sizeof(struct foo))) != NULL){
 foop- f_id = id;
 foop- f_count = 1;
 if(pthread_mutex_init( foop- f_lock, NULL) != 0){
 free(foop);
 return NULL
 /*...continue initialization...*/
 return foop;
void foo_hold(struct foo *foop){ // add a reference to the object
 pthread_mutex_lock( foop- f_lock);
 foop- f_count++;
 pthread_mutex_unlock( foop- f_lock);
void foo_rele(struct foo *foop){ // release a reference to the object
 pthread_mutex_lock( foop- f_lock);
 if(foop- f_count  0){
 pthread_mutex_unlock( foop- f_lock);
 pthread_mutex_destroy( foop- f_lock);
 free(foop);
 }else{
 pthread_mutex_unlock( foop- f_lock);

  为防止线程在获取锁时永久堵塞,能够运用函数 pthread_mutex_timedlock。
#include pthread.h 
#include time.h 
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr);
 /* 回来值:若成功,回来 0;不然,回来过错编号 */

  该函数与 pthread_mutex_lock 根本等价,但它答应绑定线程堵塞时间。当抵达超时时间时,它不会对互斥量进行加锁,而是回来过错码 ETIMEDOUT。这儿的时间参数是一个肯定时间。
  下面这个示例经过对已有的互斥量进行再次加锁(这通常会形成死锁)来演示了如何用 pthread_mutex_timedlock 来防止永久堵塞。
#include stdio.h 
#include stdlib.h 
#include string.h 
#include time.h 
#include pthread.h 
void pr_time(struct timespec tout){
 char buf[64];
 struct tm *tmp = localtime( tout.tv_sec);
 strftime(buf, sizeof(buf), "%r", tmp);
 printf("current time is: %s\n", buf);
int main(void){
 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_lock( lock);
 printf("mutex is locked\n");
 struct timespec tout;
 clock_gettime(CLOCK_REALTIME, tout);
 tout.tv_sec += 5; // 5 seconds from now
 // caution: this could lead to deadlock
 int err = pthread_mutex_timedlock( lock, tout);
 clock_gettime(CLOCK_REALTIME, tout);
 pr_time(tout);
 pr_time(tout);
 if(err != 0)
 printf("cant lock mutex again: %s\n", strerror(err));
 else
 printf("mutex locked again!\n");
 exit(0);

  编译后运转:
$ gcc timeoutLock.c -lpthread -lrt -o timeoutLock.out
$ ./timeoutLock.out 
mutex is locked
current time is: 10:37:07 AM
current time is: 10:37:12 AM
cant lock mutex again: Connection timed out

  说完互斥量,接下来再说说读写锁。
  读写锁也称同享互斥锁,它能在读取数据频率远高于写数据时供给比互斥量更高的并发性。当读写锁在写形式下时,它所维护的数据就能够被安全地修正,由于一次只需一个线程能够具有写形式的锁。而当它在读形式下时,只需线程先获取了读形式下的读写锁,该锁所维护的数据就能够一起被多个取得读形式锁的线程读取。为防止读形式锁长时间占用,一般假如有一个线程企图以写形式获取锁时,读写锁通常会堵塞随后的读形式锁恳求。
  与互斥量相同,读写锁在运用前有必要初始化,在开释其底层内存前有必要毁掉。
#include pthread.h 
int pthread_rwlock_init( pthread_rwlock_t *restrict rwlock,
 const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock *rwlock);
 /* 两个函数回来值:若成功,回来 0;不然,回来过错编号 */

  attr 参数是读写锁的特点,为 NULL 表明运用默许特点。XSI 扩展中也界说了 PTHREAD_RWLOCK_INITIALIZER 常量,用来对静态分配的读写锁进行初始化。
  能够调用 pthread_rwlock_rdlock 和 pthread_rwlock_wrlock 别离在读形式和写形式下确定读写锁,这两种方法都能够调用 pthread_rwlock_unlock 来进行解锁。
#include pthread.h 
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
 /* 三个函数回来值:若成功,回来 0;不然,回来过错编号 */

  各种完成或许会对同享形式下可获取的读写锁的次数进行约束,所以应该查看 pthread_rwlock_rdlock 的回来值。
  Single UNIX Specification 还界说了读写锁原语的条件版别和带有超时的读写锁函数。
#include pthread.h 
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_timedrdlock( pthread_rwlock_t *restrict rwlock,
 const struct timespec *restrict tsptr);
int pthread_rwlock_timedwrlock( pthread_rwlock_t *restrict rwlock,
 const struct timespec *restrict tsptr);
 /* 一切函数回来值:若成功,回来 0;不然,回来过错编号 */

  能够获取锁时,前两个函数回来 0,不然,它们回来过错 EBUSY。后两个函数假如在抵达指定的时间时还不能获取锁就将回来 ETIMEDOUT 过错。
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表威尼斯人立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1
  • 2
  • 3
  • 4

    文件链接函数ITeye

    文件,链接,函数
  • 5

    centos 布置ITeye

    装置,数据库,修正
  • 6
  • 7

    ubuntu 虚拟化 virt指令ITeye

    虚拟机,虚拟,办理
  • 8
  • 9

    linux 指令ITeye

    指令,供给,特定
  • 10

    linux封闭sendmail效劳ITeye

    封闭,效劳,发动