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
- c/c++线程--2线程同步
- C#lock线程同步
- C# 线程同步问题
- Linux C线程同步
- C/C++线程同步
- linux c 线程同步
- Linux C编程--线程操作2--线程同步详解
- Linux C 线程同步实例
- C++【线程同步】-临界区同步
- Linux C 信号、线程同步、线程互斥锁、线程条件变量
- C #中的几个线程同步对象方法
- C #中的几个线程同步对象方法
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- Visual C 线程同步技术剖析
- C #中的几个线程同步对象方法
- C #中的几个线程同步对象
- 《windows via C++》之windows线程同步
- 科研心酸历程
- Y Combinator
- 5.14异常
- Swift Optionals & Implicitly Unwrapped Optionals
- AStyle2.02在VS2008下的使用
- c/c++线程--2线程同步
- Android Studio抽取代码的方法
- Windows 下80端口被进程 System & PID=4 占用的解决方法
- HDOJ 继续畅通工程 1879(最小生成树)
- 汇编求和实验
- iphone 自学开发(二)图片轮播器的实现
- 盒子与球
- C++如何调用DLL呢,有两种,一种是静态,另外一种是动态,即通过调用windowsAPI 来加载和卸载DLL,具体思路:
- Linux删除文件后空间没有释放