线程同步的方法
1.互斥锁
互斥锁通过锁机制来实现线程间的同步。在同一时刻只允许一个线程执行一个关键部分代码。
函数 | 功能 |
pthread_mutex_init 函数 | 初始化一个互斥锁 |
pthread_mutex_destroy函数 | 注销一个互斥锁 |
pthread_mutex_lock 函数 | 加锁,如果不成功,阻塞等待 |
pthread_mutex_unlock 函数 | 解锁 |
pthread_mutex_trylock 函数 | 测试枷锁,如果不成功则立即返回,错误码EBUSY |
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
另外一种方式是通过pthread_mutex_init 函数初始化互斥锁,该函数的原型如下:
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_t *mutexattr);
//mutexattr表示互斥锁的属性,如果为NULL则使用默认属性。
属性值 | 意义 |
PTHREAD_MUTEX_TIMED_NP | 普通锁:当一个线程加锁后,其余请求锁的线程形成等待队列,解锁后按优先级获得锁 |
PTHREAD_MUTEX_RECURSIVE_NP | 嵌套锁:允许一个线程对同一个锁加锁多次,并通过多次unlock解锁。如果是不同线程请求,则在解锁时重新竞争 |
PTHREAD_MUTEX_ERRORCHECK_NP | 检错锁:在同一个线程请求同一个锁的情况下,返回EDEADLK,否则执行的动作与类型PTHREAD_MUTEX_TIMED_NP相同 |
PTHREAD_MUTEX_ADAPTIVE_NP | 适应锁:解锁后重新竞争 |
初始化以后,就可以给互斥锁加锁了。加锁有两个函数:pthread_mutex_lock()和pthread_mutex_trylock()。原型如下:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
用pthread_mutex_lock()加锁时,如果mutex已经被锁住,当前尝试加锁的线程就会阻塞,直到互斥锁被其他线程释放。当pthread_mutex_lock()函数返回时,说明互斥锁已经被当前线程成功加锁。pthread_mutex_trylock()函数则不同,如果mutex已经被加锁,他将立即返回,返回的错误码为EBUSY,而不是阻塞等待。
函数pthread_mutex_unlock用来解锁,函数原型如下:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
用函数pthread_mutex_unlock解锁时,要满足两个条件:一是互斥锁必须处于加锁状态,二是调用本函数的线程必须是给互斥锁加锁的线程。解锁后如果有其他线程在等待互斥锁,等待队列中的第一个线程将获得互斥锁。
当一个互斥锁使用完毕后,必须使用pthread_mutex_destroy函数进行清除。该函数原型如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
清除锁时要求当前处于开放状态,若锁处于锁定状态,函数返回EBUSY,成功时返回0。
例:
2.条件变量
条件变量是利用线程间共享的全局变量进行同步的一种机制。条件变量宏观上类似if语句,符合条件就可以执行某段程序,否则只能等待条件成立。
函数 | 功能 |
pthread_cond_init函数 | 初始化条件变量 |
pthread_cond_wait函数 | 基于条件变量阻塞,无条件等待 |
pthread_cond_timedwait函数 | 阻塞直到指定事件发生,计时等待 |
pthread_cond_signal函数 | 接触特定线程的阻塞,存在多个等待线程是按入队顺序**其中一个 |
pthread_cond_broadcast函数 | 接触所有线程的阻塞 |
pthread_cond_destroy函数 | 清除条件变量 |
上一篇: 读《Java2核心技术》第五章