OSTEP:27 Thread Api
锁
POSIX互斥锁
使用锁之前先初始化
#include <pthread.h>
静态直接使用宏初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
动态使用初始化函数int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
pthread_mutex_init(mutex,NULL)和用PTHREAD_MUTEX_INITIALIZER宏效果一样
attr属性
int pthread_mutexattr_gettype(pthread_mutexattr_t *attr,int *kind);
得到后
int pthread_mutexattr_settype(pthread_mutexattr_t *attr,int kind);
;来设置
PTHREAD_MUTEX_NORMAL
:普通类型互斥锁,不提供死锁检测或者错误检查。PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平
PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样保证当不允许多次加锁时不出现最简单情况下的死锁。
进程间共享(pshared):可以设置为
PTHREAD_PROCESS_PRIVATE
或PTHREAD_PROCESS_SHARED
。默认为PTHREAD_PROCESS_PRIVATE
,表示仅在同一进程内共享。成功返回0,失败非0
加锁 解锁
加锁,互斥锁加锁状态线程进入等待(阻塞)状态,直到互斥锁释放
int pthread_mutex_lock(pthread_mutex_t* mutex);
加锁 互斥锁加锁状态线程直接返回非0
int pthread_mutex_trylock(pthread_mutex_t* mutex);
加锁,阻塞到tsptr指定时间的thread_mutex_lock,超时或获取锁后返回
int pthread_mutex_timedlock(pthread_mutex_t mutex, const struct timespec *tsptr);
/*
struct timespec {
time_t tv_sec; // 秒
long tv_nsec; // 纳秒
};
*/
使用时可以
struct timespec time_out;
clock_gettime(CLOCK_REALTIME, &time_out);
time_out.tv_sec += seconds;
pthread_mutex_timedlock(mutex,&time_out)解锁
int pthread_mutex_unlock(pthread_mutex_t* mutex);
成功返回0,失败非0
销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
要求锁当前初始化过且处于开放状态
成功返回0,失败非0
|
条件变量
如果一个线程在等待另一个线程继续执行某些操作,条件变量就很有用,或者说是利用线程间共享的全局变量进行同步的机制,和互斥锁一起使用,避免竞态条件
条件变量初始化
和锁差不多
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
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_timedwait(pthread_cond_t *cond, pthread_mutex_t*mutex, const struct timespec *abstime);
比pthread_cond_wait多了限定的等待时间,abstime内没由被唤醒,上锁,结束等待,返回ETIMEOUT
>>>唤醒
int pthread_cond_signal(pthread_cond_t *cond);
使在条件变量上等待的线程中的一个线程重新开始,优先级高等待时间长的线程先开始
int pthread_cond_broadcast(pthread_cond_t *cond);
唤醒所有条件变量上等待的线程
销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond)
使用前必须没有在该条件变量上等待的线程
|