多线程中互斥锁的问题

最近在多线程编程中遇到了这样一个情况,程序中有一些变量是全局有效的,多个线程都要访问,由于没有考虑太多,导致线程出现一些问题。
于是乎,就想到了互斥锁,可是遇到了更严重的情况:有些线程执行一段时间后会被其父线程杀掉,假若此时它已对互斥锁执行了加锁操作而又未解锁的话,就造成了死锁的情况,导致程序频频出错。
这的确是一个令人困惑的问题,如何在线程被杀掉后还能够将锁解开着实令我为难了。
还好,线程的加锁、解锁是通过一个函数来进行的,函数入口处加锁、出口处解锁。于是乎,灵光一闪,我何不声明一个类呢,该类实例在函数入口处声明对互斥锁进行加锁操作,出口处解锁。
哈,为了确保加锁、解锁一定是配对的,我们何不利用一下C++里面类的构造函数和析构函数呢。如果我不通过new的方式声明该类实例,而是直接将内存分配在栈上,在函数出口处无论如何它都会被析构的。
请看:
TLock类头文件:

#ifndef _TLOCK_
#define
_TLOCK_

// 调试输出宏
#define _MY_TEST_
#undef
_MY_TEST_


// 名称:自动加锁、解锁类TLock
// 功能:为多线程提供加、解锁功能
// 用法:不要采用new的方法来声明实例,否则自动加解锁功能将失效

#include <iostream.h>
#include
<pthread.h>

#ifdef
DEBUG
    #include "
LOG.hpp"
#endif

static
pthread_mutex_t lockMutex=PTHREAD_MUTEX_INITIALIZER;

class TLock
{
    private:
        pthread_mutex_t *mylock;

    public:
        TLock(pthread_mutex_t *lock);
        ~TLock();
};


#ifdef DEBUG
extern
LOG log;
extern unsigned long
LOG_DEV;
#endif


#endif


TLock类实现文件: 

#include "TLock.hpp"

// 在函数中直接声明TLock类实例,可以确保该函数结束时互斥锁自动解锁

// TLock构造函数
TLock::TLock(pthread_mutex_t *lock)
{
    #ifdef _MY_TEST_
        cout << "begin to lock mutex..." << endl;
    #endif

    #ifdef DEBUG
        log.write(LOG_DEV|TRIVAL|LOG_TIME_TID, "线程加锁操作.../n");
    #endif

    mylock = lock;
    pthread_mutex_lock(mylock); // 加锁操作
}

// TLock析构函数
TLock::~TLock()
{
    #ifdef _MY_TEST_
        cout << "begin to unlock mutex..." << endl;
    #endif

    #ifdef DEBUG
        log.write(LOG_DEV|TRIVAL|LOG_TIME_TID, "线程解锁操作.../n");
    #endif

    pthread_mutex_unlock(mylock); // 解锁操作
}

各位看明白了吧,其实是很简单的。我在需要加解锁的函数中是这样加解锁的:
    int myfunc(int index)
    {
        TLock lock(&lockMutex);
        //...
    }

关键在这里:TLock lock(&lockMutex);
构造函数中将mp(互斥锁指针)传进去自动加锁,然后就不管了,在函数myfunc退出时系统会自动的清除TLock的实例lock,因为它是被声明在栈上的。而作为一个类,被清除时析构函数一定会及时登场的,于是乎,我们可爱的互斥锁就不得不被解锁 ^_^

后话,修改后的加解锁操作表现的好像还不错,程序也稳定了不少。如果你也遇到了类似的问题,不妨试一试这个用法。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值