//1.互斥
<pthread.h>
//互斥量数据类型:
pthread_mutex_t mutex;
//初始化互斥量:
int pthread_mutex_init(ptread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//清理互斥量
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);//此函数与上面的区别是不会阻塞,如果可以加锁则加锁后返回,否则立即返回EBUSY
//解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//2.读写锁
//读写锁特点:当已经被加了读锁时,其他的读模式锁请求仍然可以访问,但是写模式锁不能访问;当写模式锁加锁时,其他的请求都不能访问。
//读锁--共享,写锁--独占;
//读写锁数据类型
pthread_rwlock_t rwlock;
//初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
//清理读写锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
//加读锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_rdlock(pthread_tryrwlock_t *rwlock);//此函数与上面的区别是不会阻塞,如果可以加锁则加锁后返回,否则立即返回EBUSY
//加写锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//此函数与上面的区别是不会阻塞,如果可以加锁则加锁后返回,否则立即返回EBUSY
//解锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
//3.条件变量
/*与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。
条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。
条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。*/
//条件变量数据类型
pthread_cond_t cond;
//初始化条件变量
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);
//清理条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
//发送信号给等待的条件变量
int pthread_cond_signal(pthread_cond_t *cond);//解除某一个线程的阻塞
int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有线程的阻塞
//使用过程中首先对互斥量加锁,然后调用条件等待pthread_cond_wait,并把加锁的互斥量传给函数。函数把调用线程放到条件等待列表中,然后对互斥量解锁,这两个操作是原子操作。这样就避免了关闭条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道。pthread_cond_wait返回时,互斥量再次被锁住。
/*4.条件变量与互斥锁、信号量的区别
1.互斥锁必须总是由给它上锁的线程解锁,信号量的挂出即不必由执行过它的等待操作的同一进程执行。一个线程可以等待某个给定信号灯,而另一个线程可以挂出该信号灯。
2.互斥锁要么锁住,要么被解开(二值状态,类型二值信号量)。
3.由于信号量有一个与之关联的状态(它的计数值),信号量挂出操作总是被记住。然而当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么该信号将丢失。
4.互斥锁是为了上锁而设计的,条件变量是为了等待而设计的,信号灯即可用于上锁,也可用于等待,因而可能导致更多的开销和更高的复杂性。
*/