POSIX信号量与互斥锁

3种用于线程同步的机制: POSIX信号量,互斥锁和条件变量
一.POSIX信号量
常用的POSIX信号量函数如下
    int sem_init(sem_t *sem, int pshared, unsigned int value); //初始化一个信号量
    int sem_destroy(sem_t *sem); //销毁信号量
    
    int sem_wait(sem_t *sem); // 以原子操作的方式将信号量的值减1
    int sem_trywait(sem_t *sem); //非阻塞版本
    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    
    int sem_post(sem_t *sem); // 以原子操作方式将信号量的值加1
    

二.POSIX互斥锁
    互斥锁可以用来保护关键代码段,以确保独占式的访问.
POSIX互斥锁相关函数
    int pthread_mutex_destroy(pthread_mutex_t *mutex); //销毁互斥锁
    int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);

    //实际上只是把互斥锁的各个字段初始化为0          
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
      
    int pthread_mutex_lock(pthread_mutex_t *mutex);  //以原子操作方式给互斥锁加锁
    int pthread_mutex_trylock(pthread_mutex_t *mutex); //非阻塞版本
    int pthread_mutex_unlock(pthread_mutex_t *mutex); // 以原子操作方式给互斥锁解锁

三. 生产者消费者问题

#include 
#include 
#include 

#include 

#include 
#include 
#include 
#include 

#define ERR_EXIT(m) \
	do \
	{	\
		perror(m); \
		exit(EXIT_FAILURE); \
	}while(0)
	
#define CONSUMERS_COUNT 1
#define PRODUCERS_COUNT 5
#define BUFFSIZE 10  // 缓冲区大小

int g_buffer[BUFFSIZE]; /// 产品ID保存在缓冲区中

unsigned short in=0;  // 从in位置放产品
unsigned short out=0;  // 从out的位置消费产品
unsigned short produce_id =0;  // 产品ID
unsigned short consume_id =0;  // 消费产品ID

sem_t  g_sem_full;  //full信号量
sem_t  g_sem_empty;  //empty信号量
pthread_mutex_t   g_mutex;  // 互斥锁


// 创建的线程ID保存在g_thread中
pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT];

///消费者
void* consume(void* arg)
{
	int num = (int)arg;
	int i;
	while(1)
	{
		printf("%d wait buffer not empty\n",num);
		sem_wait(&g_sem_empty);
		pthread_mutex_lock(&g_mutex);
		
		//打印仓库状态
		for(i=0;i


四. 自旋锁与读写锁

1.自旋锁
    (1)自旋锁类似于互斥锁,它的性能比互斥锁更高
    (2)自旋锁与互斥锁很重要的一个区别在于,线程在申请自旋锁的时候,线程不会被挂起,处于忙等待状态
      int pthread_spin_destroy(pthread_spinlock_t *lock);
      int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
      int pthread_spin_lock(pthread_spinlock_t *lock);
      int pthread_spin_trylock(pthread_spinlock_t *lock);
      int pthread_spin_unlock(pthread_spinlock_t *lock);

2.读写锁
    (1)只要没有线程持有给定的读写锁用于写,那么任意数目线程可以持有读写锁用于读.
    (2)仅当没有线程持有某个给定的读写锁用于读或者用于写时才能分配读写锁用于写.
    (3)读写锁用于读称为共享锁,读写锁用于写称为排他锁.
    int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    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_trywrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);


你可能感兴趣的:(linux网络编程,POSIX信号量,互斥锁,生产者与消费者问题,线程,自旋锁)