线程间同步:
<h4>1.互斥量pthread_mutex_t</h4>
在使用前必须进行初始化:
<pre lang="c" escaped="true">
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
</pre>
如果动态地分配互斥量(例如通过malloc函数), 那么在释放内存前需要调用pthread_mutex_destroy.
<pre lang="c" escaped="true">
int pthread_mutex_destroy(pthread_mutex_t *mutex);
</pre>
如何对互斥量的操作,加锁与解锁:
<pre lang="c" escaped="true">
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
</pre>
避免死锁的方式:
最好是有顺序的进行加锁与解锁,不要嵌套太多的锁。另外可以用pthread_mutex_trylock()接口避免死锁,如果已经占有某些锁而且pthread_mutex_trylock()返回成功,则可以前进,但是如果不能获得锁,可以先释放已经占有的锁,做好清理工作,然后过一段时间重新尝试。
<h4>2.读写锁又叫共享-独占锁</h4>
读写锁与互斥量类似,不过读写锁允许更高的并行性。
读写锁有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多线程可以同时占有读模式的读写锁。
<blockquote>但当读写锁处于读模式锁住状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求。这样可以避免读模式锁长期占用,而等待的写模式锁请求一直得不到满足。</blockquote>
读写锁与互斥量一样,在使用之前必须初始化,在释放它们底层的内存前必须销毁。
<pre lang="c" escaped="true">
#include <pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
</pre>
记得用了ptrhead_rwlock_init()就要记得用pthread_rwlock_destroy()进行销毁。
<pre lang="c" escaped="true">
#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);
</pre>
一定要记得检查读写锁获取时的返回值。另外还定义了有条件的读写锁:
<pre lang="c" escaped="true">
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
</pre>
<h4>3.条件变量</h4>
条件变量是线程可用的另一种同步机制,条件变量与互斥量一起使用,条件本身是由互斥量保护的。
<pre lang="c" escaped="true">
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
</pre>