您的位置:程序门 -> vc/mfc -> 进程/线程/dll



求教,多线程安全问题?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


求教,多线程安全问题?[已结贴,结贴人:lindex]
发表于:2007-10-04 16:04:31 楼主
有下面这样一个函数
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;            
}


发表于:2007-10-04 16:34:211楼 得分:50
首先定义一个类包装critical_section

class   cmycritical
{
              critical_section   m_section;
};

把critical_section当作他的一个成员对象

给这个类提供以下三个方法

1.   构造函数,在这个函数里初始化临界区
2.   析构函数,在这里释放
3.   operator   critical_section,这里直接返回那个成员

这样你可以用static   cmycritical对象定义临界区,让他自动初始化
后面就可以直接使用entercritcalsection   来guard了
发表于:2007-10-04 16:40:282楼 得分:0
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;              
}  
发表于:2007-10-04 16:45:463楼 得分:0
谢谢arong,但是问题出在,我这个函数是c语言的,虽然c语言和c++语言差别不是很大,但是在内存管理上还是大有不同,如果撇开c++,用c语言如何实现?
发表于:2007-10-04 18:30:344楼 得分:50
static   critical_section   cs;    
应放在call_in_thread函数外面:   程序启动时初始化cs,退出时销毁cs。

另,call_in_thread函数的写法有些问题,改造为:

c/c++ code
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; }
发表于:2007-10-05 09:47:165楼 得分:0
这样做安全否?是这样的,我如果把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;              
}  
发表于:2007-10-05 11:42:486楼 得分:0
不安全!初始化cs应放在外面。试想:某线程进入了cs可是又被其他线程初始化了会怎么样?
另外有些退出路径没有执行必要的清理,参考上面的那个版本。
发表于:2007-10-05 14:05:037楼 得分:0
c语言没有好办法,你必须确保你调用这个函数前初始化他,也不能使用static变量,必须在函数外定义
发表于:2007-10-05 14:06:078楼 得分:0
dyw说的对,对于c语言,没有其他解决之道,你必须放在函数外定义和初始化。而且确保这个函数在被调用之前必须被初始化


快速检索

最新资讯
热门点击