c/c++线程--2线程同步

来源:互联网 发布:icmp.dll被java嗲用 编辑:程序博客网 时间:2024/05/01 02:14

c/c++线程--2线程同步


线程同步的方式
1.互斥锁
2.条件变量
3.读写锁

异步方式
信号

同步方式:
3种锁都需要创建和销毁。还有属性参数,默认属性的话,这个参数传NULL。

互斥锁通信机制

  • 二元变量,解决线程间同步问题。
  • 同步:先后顺序。
  • 以排他方式防止数据结构被并发的修改;

控制逻辑:
a.访问前申请,如果处于开锁状态,则申请到该锁,并占有。
如果处于锁定状态,默认阻塞当前线程。
b.只有锁定该互斥锁的线程才能释放该互斥锁,其他线程的操作无效。


初始化,销毁互斥锁
互斥锁,互斥锁属性的变量类型
pthread_mutex_t
pthread_mutexattr_t


/// 成功返回0/* Initialize a mutex.  */extern int pthread_mutex_init (pthread_mutex_t *__mutex,       const pthread_mutexattr_t *__mutexattr)     __THROW __nonnull ((1));/* Destroy a mutex.  */extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)     __THROW __nonnull ((1));


申请互斥锁
/// 非阻塞/* Try locking a mutex.  */extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)     __THROWNL __nonnull ((1));/// 阻塞/* Lock a mutex.  */extern int pthread_mutex_lock (pthread_mutex_t *__mutex)     __THROWNL __nonnull ((1));

释放互斥锁

/// !!拥有该锁的线程才能开锁。/* Unlock a mutex.  */extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)     __THROWNL __nonnull ((1));


条件变量通信机制

不仅互斥的访问变量,而且当且仅当满足一定条件时,线程才会执行。
如果只使用互斥锁,那么当出现满足的条件时,还要竞争资源。因此,用互斥锁目标线程可能得不到执行的机会。

条件变量解决:
根据保护数据的当前值来调整线程的行为;类似于信号。
条件变量不能单独使用,必须和互斥锁一起使用。
每个线程对应函数的第一条语句使用锁定互斥量的语句,最后一条语句使用解锁互斥量的语句。


条件变量

pthread_cond_t

pthread_condattr_t


a.创建,销毁

/* Initialize condition variable COND using attributes ATTR, or use   the default values if later is NULL.  */extern int pthread_cond_init (pthread_cond_t *__restrict __cond,      const pthread_condattr_t *__restrict __cond_attr)     __THROW __nonnull ((1));/* Destroy condition variable COND.  */extern int pthread_cond_destroy (pthread_cond_t *__cond)     __THROW __nonnull ((1));

b.等待等待之前要加互斥锁。

阻塞时,隐含释放关联的互斥锁。没唤醒时,隐含加锁。
/* Wait for condition variable COND to be signaled or broadcast.   MUTEX is assumed to be locked before.   This function is a cancellation point and therefore not marked with   __THROW.  */extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,      pthread_mutex_t *__restrict __mutex)     __nonnull ((1, 2));     /* Wait for condition variable COND to be signaled or broadcast until   ABSTIME.  MUTEX is assumed to be locked before.  ABSTIME is an   absolute time specification; zero is the beginning of the epoch   (00:00:00 GMT, January 1, 1970).   This function is a cancellation point and therefore not marked with   __THROW.  */extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,   pthread_mutex_t *__restrict __mutex,   const struct timespec *__restrict __abstime)     __nonnull ((1, 2, 3));


c. 唤醒

隐含释放关联的互斥锁。
即使没有线程相应,也会返回成功。
/// 唤醒一个/* Wake up one thread waiting for condition variable COND.  */extern int pthread_cond_signal (pthread_cond_t *__cond)     __THROWNL __nonnull ((1));/// 唤醒所有/* Wake up all threads waiting for condition variables COND.  */extern int pthread_cond_broadcast (pthread_cond_t *__cond)     __THROWNL __nonnull ((1));    

在我看来,条件变量更像是一种信号。 

程序架构
生产者-消费者

putData()
{
lock();
while(仓库满)
{
wait(hasSlot);
}
put(data);
signal(hasData);
unlock();
}

getData()
{
lock();
while(仓库空)
{
wait(hasData);
}
data = get();
signal(hasSlot);
unlock();
}

读写锁通信机制

互斥锁,条件变量都是互斥的访问临街资源。
对于数据的读写操作来说,写写和读写冲突的。如果只是读操作,那么可以不冲突。
如果采用排他的机制来操作,可能会降低效率。
读写锁,就可以解决这样的问题。和数据库的逻辑一样。

控制逻辑:
  • 如果申请了读锁,其他线程也可以申请读锁,但是不能申请写锁。
  • 如果申请了写锁,其他线程既不能申请读锁,也不能申请写锁。
读写锁变量
/* Data structure for read-write lock variable handling.  The
   structure of the attribute type is not exposed on purpose.  */
pthread_rwlock_t rwlock;
pthread_rwlockattr_t rwlockattr;

a. 创建,销毁
/* Initialize read-write lock RWLOCK using attributes ATTR, or use   the default values if later is NULL.  */extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,const pthread_rwlockattr_t *__restrict__attr) __THROW __nonnull ((1));/* Destroy read-write lock RWLOCK.  */extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)     __THROW __nonnull ((1));

b. 申请,释放
申请读锁
/* Acquire read lock for RWLOCK.  */extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)     __THROWNL __nonnull ((1));/// 非阻塞/* Try to acquire read lock for RWLOCK.  */extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)  __THROWNL __nonnull ((1));

申请写锁
/* Acquire write lock for RWLOCK.  */extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)     __THROWNL __nonnull ((1));/// 非阻塞/* Try to acquire write lock for RWLOCK.  */extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)     __THROWNL __nonnull ((1));

释放锁--无论是读锁还是写锁
/* Unlock RWLOCK.  */extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)     __THROWNL __nonnull ((1));

说明:

释放逻辑

(1).如果释放读锁,但还有其他线程占用读锁,读锁依然锁定。没有,则解锁。
(2).如果释放写锁,则直接解锁。




0 0
原创粉丝点击