Linux的信号量(semaphore)与互斥(mutex)
在多线程编程中,出于各种原因我们会用到锁或者信号量等各种机制对一些操作进行控制,这里面就讲述linux C编程时,常用的两种方式:信号量方式 和 锁方式
锁:用来做互斥,用于保护某个资源在当下只能被多个线程中的一个访问,用于一个进程的多线程之间
信号量:用来做同步,用于保证多个线程之间按照既定顺序执行步骤,可以用于一个进程的多线程,据说也可以用于多个进程
wxy:锁是为了保护某个资源,从上锁的那一刻,如果不涉及资源(多线程可访问的那些变量?或者叫全局变量,或者类中的成员变量等等...),照样可以走下去
信号量是为了同步的,从上信号量那一刻,就不能动了,除非另一个想成给我发信号(post),说你可以继续了,与是我才继续走下去
一:Mutex(锁)
1,用法举例(经试验)
//0.头文件引入 #include <mutex> //1.定义锁 mutex mutex_me;
++++++线程1+++++++++ +++++++++线程2+++++++++
//2.上锁 //2.上锁 mutex_me.lock() mutex_me.lock() /*资源*/ //3.解锁 mutex_me.unlock() /*资源*/ //3.解锁
mutex_me.unlock()
2,函数解析
void lock() { int __e = __gthread_mutex_lock(&_M_mutex); } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex){ if (__gthread_active_p ()) //如果当前线程是活跃的 return __gthrw_(pthread_mutex_lock) (__mutex); else return 0; }
二,信号量
1,用法举例(未经试验)
//0.头文件引入
#include <semaphore.h>
//1.定义/创建信号量
sem_t semaphoretcpItem;
sem_init(&semaphoretcpItem, 0, 1);
++++++线程1+++++++++ +++++++++线程2+++++++++ +++++++线程3++++++
//step1:等待信号量 //step2.第一次释放信号量
while(true){ sem_post(&semaphoretcpItem);
sem_wait(&semaphoretcpItem);
//step3.第二次释放信号量
sem_post(&semaphoretcpItem);
step4 * 3次
}
解析:
1.wait的时候要求信号量>0,而初始信号量时1,因此wait语句顺利通过,通过的同时信号量-1,此时线程1中的while第一轮循环是可以执行的;
2.如果线程2和3都没有什么动作,则线程1在进入第二轮循环的时候阻塞在那里,直到线程2或3有post,于是信号量+1;
3,整体总结起来就是:线程1是否往下执行就看其他线程是否有动作,这样的逻辑就好比生产者消费者
我(线程1)不瞎执行,累够呛,只有需要我干活的时候(其他线程)我再执行....
2,相关函数解析
sem_init():用来初始化一个信号量。
它的原型为:extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));
sem为指向信号量结构的一个指针;
pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;
value给出了信号量的初始值。
sem_post( sem_t *sem ):用来增加信号量的值。
当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。
sem_wait( sem_t *sem ):被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。
sem_trywait ( sem_t *sem ):是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。
sem_destroy(sem_t *sem):用来释放信号量sem。