Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1467351
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类:

2012-05-04 21:47:32

   在多线程并发执行的环境中就有可能出现冲突操作的情况,使用互斥量能进行线程间的同步,使线程在访问共享资源时受到用户的控制

1.互斥量的初始化与销毁

   互斥量是一种锁,在访问共享资源时对其加锁,在访问结束时释放锁,这样可以保证在任意时间内,只有一个线程处于临界区中。

  注:任何想要进入临界区的线程都要对锁进行测试,如果该锁已经被某一个线程所持有,则测试线程就会被阻塞,知道该锁被释放,线程会重复上述过程。

linux环境下使用pthread_mutex_t数据类型表示互斥量,这是一个联合union

在用户使用互斥量之前要对其进程初始化,使用pthread_mutex_init函数对互斥量进行初始化,

int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr *restrict attr)

   第一个参数是互斥量的指针,初始化后返回该指针给调用者;第二个参数是互斥量的属性,在此先将该参数设置为NULL,内核会使用默认属性对互斥量进程初始化;

  返回值:成功,返回0,;失败返回错误号。

2.得到与释放互斥量

   互斥量对用户来说是透明的数据结构,用户不可以直接对其进行操作,而应当使用系统提供的操作互斥量的函数接口。linux环境使用一组函数操作互斥量,得到互斥量,释放互斥量。

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

   前两个函数用于得到一个互斥量的锁(对临界区加锁),第3个函数用于释放互斥量的锁,对临界区解锁。

   pthread_mutex_lock用于获取互斥量的锁,如果该互斥量的锁已经被某一个线程得到,那么该函数会导致线程阻塞,直到互斥量的锁被释放;

   成功,返回0,失败返回错误号。

注:pthread_mutex_lock与trylock函数有一点不同,trylock函数在得不到指定互斥量的锁时不会导致线程阻塞,而是立即返回一个错误编号EBUSY,表示所请求的锁处于繁忙状态。这就是trylock的意义,try。

pthread_mutex_unlock用于释放一个互斥量的锁,其参数表示需要释放锁的互斥量。


3.线程同步---使用读写锁

  读写锁是另一种线程之间同步的操作,如果没有同步操作,会导致线程在执行时出现与时间有关的错误。

(1)初始化与销毁读写锁

   读写锁与互斥量相似,但是并行性更高,原因在于互斥锁每次只有一个线程可以得到锁进行操作,其余的线程阻塞。读写锁的好处是线程根据操作类型分为两类:读线程+写线程。读线程只对共享资源进行读操作,并不改变共享资源;写线程对共享资源进行写操作,会改变共享资源。

  因此,对于多个读线程可以共同占有一个读写锁,对于写线程,任意时刻只有一个线程占有。

如果对共享资源做读操作的线程远大于写线程的时候,使用读写锁可以极大的提高线程的并发度。

  linux环境下使用pthread_rwlock_t结构类型表示读写锁,在使用读写锁之前要对其进行初始化。

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *attr);

第一个参数是读写锁的指针,读写锁在该函数内被初始化,并通过该参数返回给调用线程。

第二个参数是读写锁的属性,通常为NULL。

当一个读写锁不再使用时,应将其销毁

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

成功销毁返回0,失败返回错误号

 

(2)得到与释放互斥锁

 linux环境下使用一组函数操作在读模式下得到读写锁:

 int  pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

 int  pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

参数表示一个读写锁,调用线程希望在读模式下得到该读写锁。如果该读写锁已经被某一个线程在读模式下得到,则测试线程仍然会得到该锁;如果该读写锁已经被某一个线程在写模式下得到,或者有一个线程在写模式下等待该锁,这时pthread_rwlock_rdlock函数会导致线程阻塞,直到读写锁被释放。

  trylock在得不到指定读写锁时,并不会导致调用线程阻塞,而是立即返回一个错误编号EBUSY,。

写模式下也有一组得到锁的函数

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

在测试线程读写锁的时候,有任意一个线程占有该锁,wrlock函数就会导致阻塞,并会导致其后所有申请该读写锁的线程阻塞等待。

两种模式下,释放一个读写锁的方式是一样的:

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

 

(3)使用互斥量与读写锁的比较

 

 

 

 

阅读(301) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~