线程同步的方法

1.线程同步的方法


  线程的同步方法有互斥锁、条件变量(cond)、读写锁和POSIX信号量。

2.互斥锁


  int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);

    初始化互斥锁。

    mutexattr的取值范围:

      (1)PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。 

      (2)PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

      (3)PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程连续加锁两次(死锁),则第二次加锁会立刻返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。

      (4)PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

    检错锁第二次加锁会直接返回EDEADLK(而不是阻塞),这样虽然不会导致死锁,但是明显是有代码问题。

  int pthread_mutex_lock(pthread_mutex *mutex);

    阻塞加锁。

  int pthread_mutex_trylock( pthread_mutex_t *mutex);

    非阻塞加锁。

  int pthread_mutex_unlock(pthread_mutex *mutex);

    解锁。

  int pthread_mutex_destroy(pthread_mutex *mutex);

    销毁锁。

3.条件变量


  int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);

    初始化条件变量。

  int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex); 

    阻塞等待信号。

  int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);

    定时等待信号。无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时调用等待函数。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP)。

  int pthread_cond_signal(pthread_cond_t *cond);

    激活单个线程,存在多个线程时,按入队顺序激活第一个。

  int pthread_cond_broadcast(pthread_cond_t *cond);

    激活所有线程。

  int pthread_cond_destroy(pthread_cond_t *cond);

    销毁。

4.读写锁


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

    初始化。

  int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

  int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

  int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout);

    加读锁。

  int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

  int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

  int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout);

    加写锁。

  int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

    销毁锁。

5.POSIX信号量


  int sem_init(sem_t *sem, int pshared, unsigned int value);

    初始化信号量,其中sem是要初始化的信号量,pshared是0表示此信号量是当前进程的局部信号量,否则这个信号量就可以在多个进程之间共享。value指定信号量的初始值。

  int sem_wait(sem_t *sem);  

    该函数以原子操作的方式将信号量的值减1。如果信号量的值为0,则阻塞等待信号量变为非0值时才返回。

  int sem_trywait(sem_t *sem);

    非阻塞等待。

  int sem_post(sem_t *sem);   

    该函数以原子操作的方式将信号量的值加1。当信号量的值大于0时,其他调用sem_wait的函数将被唤醒。

  int sem_destroy(sem_t *sem);

    销毁。

6.问题


  问题1:信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。

 

posted on 2019-02-28 14:41  能量星星  阅读(770)  评论(0编辑  收藏  举报

导航