参考:《Effective C++》,《Unix环境高级编程》,博客:http://blog.csdn.net/morewindows/article/details/7823572
本文只讨论Unix下的信号量与互斥锁两种同步于互斥方法。
互斥锁pthread_mutex_t )故名思意就是不能同时访问,信号量(sem_t)一般用于线程的同步,当然也可以用于线程互斥,但是互斥锁与信号量有一个很大的不同,当一个线程获得锁后必须又该线程释放,如果该线程不是放那么其它线程就无法获得从而造成死锁,对于信号量其本身就用于线程同步,所以不一定由已经获得该信号量的线程释放。这样运用互斥锁时就极有可能由于线程提前pthread_exit退出(不能调用exit,如果exit整个进程就会退出测试时注意 ),或者其他原因导致线程提前退出。这样就无法释放释放锁从而导致死锁。这个问题去年和进入企鹅的师兄讨论时没有找到好的解决方法,最近正在浏览《EffectiveC++》是无意中看到了作者的解决方法经典之极。
1,首先要做的就是对锁进行一个封装。如下
class Lock
{
public:
explicit Lock( pthread_mutex_t *lock):Mutex(lock){pthread_mutex_lock(Mutex);}
~Lock(){pthread_mutex_unlock(Mutex);}
private:
pthread_mutex_t *Mutex;
}
我们来看一下上面的封装,在构造函数中我们以lock初始化Mutex并调用pthread_mutex_lock加锁,在析构函数中我们调用pthread_mutex_unlock解锁。至此我们已经将所封装好了。下面我们来看如何运用。
2,运用 下面的代码都是简化的形式。
线程函数 void *locktest(int*arg)
{
/*do somethting before lock ****/
Lock Lock(lock);
/*do something in lock********/
}
上面的代码即为引用代码,有些人可能会奇怪只有加锁而没有解锁呀???那么如何解锁呢??答案是在线程结束时,Lock为内部变量在函数出栈是销毁Lock时自动调用析构函数解锁。当然就光看上面这个程序是由很大问题的那就是锁是在整个函数内都是锁住的,也就是锁锁住的是整个函数,的确。能够解决的办法就是在执行互斥区域时我们将那部分执行代码封装在一个函数内,这样避免长时间锁住整个函数。