linux下多线程同步机制之信号量、互斥量、读写锁、条件变量
2013-10-29 16:39
841 查看
之前有写过类似的博客,这东西不用老忘,现在又有更清晰的理解了。
一、信号量
编译时候加入-lrt
信号量最基本的两个操作就是PV操作:P()操作实现信号量减少,V()操作实现信号量的增加
信号量的值取决于信号量的类型,信号量的类型有多种:
(1)二进制信号量:0与1.
当值=1时,信号量可用,当值=0时候,信号量不可用,这里就可以利用P()V()操作来实现,如果=0时候,线程阻塞在P()操作
(2)计数信号量
某个非负整数,初始值表示可用的资源数,例如我们实现两个线程,一个线程专门执行V()操作 另一个专门执行P()操作 那么生产者,消费着的行为就是如此!!
我们发现,上面这种方式不是一个很好的原子操作!
当然,也可以利用0-1这种实现原子操作
就是将信号量初始化为1,然后Producer()和Consuer()这两个线程都执行
sem_wait()
受限制的资源操作
sem_post()
这种方式就可以阻塞另一个想要占用同一个资源的线程
信号量的好处就是可以实现进程间的通信!
二、POSIX还提供了另一种实现机制,利用MUTEX pthread_mutex_t
编译时候加入-lpthread
#include <pthread.h>
#include <fcntl.h>
这个互斥量的使用方式
初始化:
mutex = PTHREAD_MUTEX_INITIALIZER;//静态初始化
pthread_mutex_init(&mutex, NULL);//动态初始化
请求占有:
pthread_mutex_lock(&mutex)
释放占有:
pthread_mutex_unlock(&mutex);
尝试占有:
pthread_mutex_trylock(&mutex);
销毁:
pthread_mutex_destroy(&mutex);
三、读写锁
互斥量信号量都是临界区实现,只有使用共享数据的线程或进程才能进入。可是,当我们有多个线程只是希望读取数据的时候,他们之间会进行阻塞,而我们并不希望这样,只希望写线程才会对别的产生阻塞
如果多个线程对共享内存进行写访问,则不允许其他线程进入临界区,如果应用程序有多个线程希望读,则可以进入临界区。
POSIX定义了类型为pthread_rwlock_t 的读写锁
初始化:
pthread_rwlock_init(pthread_rwlock_t*, attr)
请求占有:
pthread_rwlock_rdlock(*lock)
pthread_rwlock_wrlock(*lock);
pthread_rwlock_timedrdlock()...
释放占有:
pthread_rwlock_unlock(*lock)
尝试和销毁
四、条件变量
互斥量通过 控制 对共享数据的访问来同步任务。条件变量可以根据数据的值来同步任务。条件变量是当一个事件发生时发送信号的信号量。一旦事情发生,可能会有多个进程或线程在等待信号。条件变量通常用于对操作的顺序进行同步。
条件变量类型pthread_cond_t
初始化:
pthread_cond_init(pthread_cond_t*,*attr)
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
发送信号:
pthread_cond_signal(*cond)
pthread_cond_broadcast(*cond)
销毁
pthread_cond_destroy(*cond);
阻塞:
pthread_cond_wait(*cond,*mutex)
一、信号量
编译时候加入-lrt
信号量最基本的两个操作就是PV操作:P()操作实现信号量减少,V()操作实现信号量的增加
信号量的值取决于信号量的类型,信号量的类型有多种:
(1)二进制信号量:0与1.
当值=1时,信号量可用,当值=0时候,信号量不可用,这里就可以利用P()V()操作来实现,如果=0时候,线程阻塞在P()操作
(2)计数信号量
某个非负整数,初始值表示可用的资源数,例如我们实现两个线程,一个线程专门执行V()操作 另一个专门执行P()操作 那么生产者,消费着的行为就是如此!!
//============================================================================ // Name : ThreadTest.cpp // Author : YLF // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <semaphore.h> #include <fcntl.h> #include <pthread.h> using namespace std; char *semName = "/SEM"; sem_t *sem; void* Producer(void* para){ int n = 10; while(n>0){ sem_post(sem); cout<<"produce"<<endl; n--; } } void* Consumer(void* para){ int n = 10; while(n>0){ sem_wait(sem); cout<<"consumer"<<endl; n--; } } int main() { sem = sem_open(semName, O_CREAT, O_RDWR, 0); pthread_t thread1,thread2; pthread_create(&thread1,NULL,Producer,NULL); pthread_create(&thread2,NULL,Consumer,NULL); pthread_join(thread1,NULL); pthread_join(thread2,NULL); sem_close(sem); sem_unlink(semName); return 0; }
produce produceconsumer consumer produce produce produce produce produce produce produce produce consumer consumer consumer consumer consumer consumer consumer consumer
我们发现,上面这种方式不是一个很好的原子操作!
当然,也可以利用0-1这种实现原子操作
就是将信号量初始化为1,然后Producer()和Consuer()这两个线程都执行
sem_wait()
受限制的资源操作
sem_post()
这种方式就可以阻塞另一个想要占用同一个资源的线程
信号量的好处就是可以实现进程间的通信!
二、POSIX还提供了另一种实现机制,利用MUTEX pthread_mutex_t
编译时候加入-lpthread
#include <pthread.h>
#include <fcntl.h>
这个互斥量的使用方式
初始化:
mutex = PTHREAD_MUTEX_INITIALIZER;//静态初始化
pthread_mutex_init(&mutex, NULL);//动态初始化
请求占有:
pthread_mutex_lock(&mutex)
释放占有:
pthread_mutex_unlock(&mutex);
尝试占有:
pthread_mutex_trylock(&mutex);
销毁:
pthread_mutex_destroy(&mutex);
三、读写锁
互斥量信号量都是临界区实现,只有使用共享数据的线程或进程才能进入。可是,当我们有多个线程只是希望读取数据的时候,他们之间会进行阻塞,而我们并不希望这样,只希望写线程才会对别的产生阻塞
如果多个线程对共享内存进行写访问,则不允许其他线程进入临界区,如果应用程序有多个线程希望读,则可以进入临界区。
POSIX定义了类型为pthread_rwlock_t 的读写锁
初始化:
pthread_rwlock_init(pthread_rwlock_t*, attr)
请求占有:
pthread_rwlock_rdlock(*lock)
pthread_rwlock_wrlock(*lock);
pthread_rwlock_timedrdlock()...
释放占有:
pthread_rwlock_unlock(*lock)
尝试和销毁
四、条件变量
互斥量通过 控制 对共享数据的访问来同步任务。条件变量可以根据数据的值来同步任务。条件变量是当一个事件发生时发送信号的信号量。一旦事情发生,可能会有多个进程或线程在等待信号。条件变量通常用于对操作的顺序进行同步。
条件变量类型pthread_cond_t
初始化:
pthread_cond_init(pthread_cond_t*,*attr)
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
发送信号:
pthread_cond_signal(*cond)
pthread_cond_broadcast(*cond)
销毁
pthread_cond_destroy(*cond);
阻塞:
pthread_cond_wait(*cond,*mutex)
pthread_mutex_t mutex, eventMutex; pthread_cond_t cond; void* ThreadA(void *para){ int num = 10; while(num>0){ pthread_mutex_lock(&mutex); num--; cout<<"ThreadA:"<<num<<endl; if(num == 6) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } } void* ThreadB(void* para){ int num = 10; pthread_mutex_lock(&eventMutex); pthread_cond_wait(&cond, &eventMutex); pthread_mutex_unlock(&eventMutex); while(num>0){ pthread_mutex_lock(&mutex); num--; cout<<"ThreadB:"<<num<<endl; pthread_mutex_unlock(&mutex); } } int main() { pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&eventMutex, NULL); pthread_t thread1,thread2; pthread_create(&thread2,NULL,ThreadB,NULL); pthread_create(&thread1,NULL,ThreadA,NULL); pthread_join(thread1,NULL); pthread_join(thread2,NULL); return 0 ; }
相关文章推荐
- Linux 多线程同步机制:互斥量、信号量、条件变量
- Linux下多线程同步方式之互斥量,信号量,条件变量
- 线程同步机制:互斥量、信号量、读写锁、条件变量
- linux c++多线程 线程私有数据 互斥量 条件变量 信号量 读写锁 自旋锁 屏障
- 【Linux】深入理解线程(线程同步、互斥量mutex、死锁、读写锁、条件变量、信号量)
- 线程同步机制:互斥量、信号量、读写锁、条件变量
- linux多线程-----同步机制(互斥量、读写锁、条件变量)
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
- linux中的互斥锁--mutex,条件变量,信号量,读写锁
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
- 【Linux】深入理解线程(线程同步、互斥量mutex、死锁、读写锁、条件变量、信号量)
- 笔记:进程间通信——同步(互斥锁、读写锁、条件变量、信号量)以及Linux中的RCU
- Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏
- linux系统中多线程同步之互斥变量、读写锁、条件变量
- Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏
- Linux 线程同步机制:互斥、读写锁、条件变量
- 线程同步机制(互斥量,读写锁,自旋锁,条件变量,屏障)
- Linux内核中锁机制之信号量、读写信号量
- linux下多线程编程原以及互锁、条件变量、读写锁、信号等通信机制
- linux多线程简单介绍-线程创建、终止、属性设置、多线程同步技术(互斥量、条件变量、信号量)