有下面这样一个函数
char *call_in_thread()
{
    static char *ret_val = NULL;    if(NULL != ret_val)
    {
        free(ret_val);
        ret_val = NULL;
    }    if(NULL == (ret_val = (char *)malloc(MAX_RET_VAL_LENGTH)))
    {
        return ret_val;
    }    ……         return ret_val;      
}我想在不改变函数原型的情况下能够在多线程环境正常工作,请教各位大侠,如何修改?
如果使用临界区,又在何时初始化和删除临界区?char *call_in_thread()
{
    static char *ret_val = NULL;
    static CRITICAL_SECTION cs;    
    EnterCriticalSection(&cs);    if(NULL != ret_val)
    {
        free(ret_val);
        LeaveCriticalSection(&cs);
        ret_val = NULL;
    }    if(NULL == (ret_val = (char *)malloc(MAX_RET_VAL_LENGTH)))
    {
        LeaveCrticalSection(&cs);
        return ret_val;
    }    ……         LeaveCriticalSection(&cs);    return ret_val;      
}

解决方案 »

  1.   

    首先定义一个类包装CRITICAL_SECTIONclass CMyCritical
    {
           CRITICAL_SECTION m_section;
    };把CRITICAL_SECTION当作他的一个成员对象给这个类提供以下三个方法1. 构造函数,在这个函数里初始化临界区
    2. 析构函数,在这里释放
    3. operator CRITICAL_SECTION,这里直接返回那个成员这样你可以用static CMyCritical对象定义临界区,让他自动初始化
    后面就可以直接使用EnterCritcalSection 来guard了
      

  2.   

    class CMyCritical
    {   CRITICAL_SECTION m_section;
    public:
       CMyCritical(){InitializeCriticalSection(&m_section);};
       operator CRITICAL_SECTION& () {return m_section;};//如果这个不行,则换一个GetCriticalSection
       ~CMyCriticalSection(){DeleteCriticalSection(&m_section);};
    };char *call_in_thread() 

        static char *ret_val = NULL; 
        static CMyCritical cs;     
        EnterCriticalSection(&cs);     if(NULL != ret_val) 
        { 
            free(ret_val); 
            LeaveCriticalSection(&cs); 
            ret_val = NULL; 
        }     if(NULL == (ret_val = (char *)malloc(MAX_RET_VAL_LENGTH))) 
        { 
            LeaveCrticalSection(&cs); 
            return ret_val; 
        }     ……          LeaveCriticalSection(&cs);     return ret_val;       

      

  3.   

    谢谢arong,但是问题出在,我这个函数是c语言的,虽然C语言和c++语言差别不是很大,但是在内存管理上还是大有不同,如果撇开c++,用c语言如何实现?
      

  4.   

    static CRITICAL_SECTION cs;  
    应放在call_in_thread函数外面: 程序启动时初始化cs,退出时销毁cs。另,call_in_thread函数的写法有些问题,改造为:char *call_in_thread() 

        static char *ret_val = NULL; 
        EnterCriticalSection(&cs);     if(NULL != ret_val) 
        { 
            free(ret_val); 
    //        LeaveCriticalSection(&cs);    // 去掉,不能Leave,还没有malloc
            ret_val = NULL; 
        } //    这里没有必要判断
    //    if(NULL == (ret_val = (char *)malloc(MAX_RET_VAL_LENGTH))) 
    //    { 
    //        LeaveCrticalSection(&cs); 
    //        return ret_val; 
    //    }       ret_val = (char *)malloc(MAX_RET_VAL_LENGTH);
          if (ret_val)
          {
           // Do something here .
           ... 
          }    LeaveCriticalSection(&cs);     return ret_val;       
      

  5.   

    这样做安全否?是这样的,我如果把cs声明在函数外部,那么就必须写一个init和delete的函数,这样不利于调用。所以还是想把cs放在函数内部。char *call_in_thread() 

        static char *ret_val = NULL; 
        static CRITICAL_SECTION cs;      InitializeCriticalSection(&cs);
        EnterCriticalSection(&cs);     if(NULL != ret_val) 
        { 
            free(ret_val); 
            ret_val = NULL; 
            LeaveCriticalSection(&cs); 
            return;
        }     if(NULL == (ret_val = (char *)malloc(MAX_RET_VAL_LENGTH))) 
        { 
            LeaveCrticalSection(&cs); 
            return ret_val; 
        }     ……          LeaveCriticalSection(&cs); 
        DeleteCriticalSection(&cs);    return ret_val;       

      

  6.   

    不安全!初始化cs应放在外面。试想:某线程进入了cs可是又被其他线程初始化了会怎么样?
    另外有些退出路径没有执行必要的清理,参考上面的那个版本。
      

  7.   

    C语言没有好办法,你必须确保你调用这个函数前初始化他,也不能使用static变量,必须在函数外定义
      

  8.   

    dyw说的对,对于C语言,没有其他解决之道,你必须放在函数外定义和初始化。而且确保这个函数在被调用之前必须被初始化