C++ 使用

boost中shared_lock和unique_lock的区别

shared_lock和unique_lock一般搭配使用,用来解决变量的读写冲突。

shared_lock是read lock,即设置读标志,同时限制写权限。
当要读取某个变量时,使用shared_lock,相当于为此变量设置了读标志位,不影响其他线程(或进程)读取该变量,但是不允许其他线程(或进程)改写该变量。
被锁后仍允许其他线程执行同样被shared_lock的代码。这是一般做读操作时的需要。

使用shared_lock上锁的代码可以被同时被多个线(或进)程访问,但是如果shared_lock不释放,那么使用unique_lock上锁的代码不可以被执行。

unique_lock是write lock,即设置写标志,同时限制读写权限
当要改写某个变量时,使用unique_lock,相当于为此变量设置了写标志位,限制其他线程(或进程)改写该变量和所有的读操作。
被锁后不允许其他线程执行被shared_lock或unique_lock的代码。在写操作时,一般用这个,可以同时限制unique_lock的写和share_lock的读。

使用unique_lock上锁后,unique_lock锁定的代码只允许当前线程(或进程)执行,不允许其他线程(或进程)执行;shared_lock锁定的代码均不允许访问,直至unique_lock被释放。

void GetFields(DBFields& _return, const std::wstring& sGUID) 
{
    printf("GetFields\n");
	boost::shared_lock< boost::shared_mutex > xLock( GetMutex(sGUID) ); 
	//用shared_lock, 其他线程不可以执行下面的SetFields(), 但可以同时执行GetFields()
	_return = GetDataPtr(sGUID)->m_oFieldData.m_oDBFields;
  }


void SetFields(const std::wstring& sGUID, const DBFields& aFields)
{    
    printf("SetFields\n");
	boost::unique_lock< boost::shared_mutex > xLock(  GetMutex(sGUID) ); 
	//用unique_lock, 其他线程一定要等到这个函数结束才可以执行SetFields()或GetFields()。
	GetSetDataPtr(sGUID)->m_oFieldData.m_oDBFields = aFields;
  }

xLock.unlock()可手动解除锁定。

解释:
以上代码用来控制对GetDataPtr(sGUID)->m_oFieldData.m_oDBFields的读写。使用boost::shared_lock锁定的代码中,包含了对GetDataPtr(sGUID)->m_oFieldData.m_oDBFields的读取操作;使用boost::unique_lock锁定的代码包含对GetDataPtr(sGUID)->m_oFieldData.m_oDBFields的改写(重赋值)操作。
即,当boost::unique_lock未锁定(即SetFields未被执行)时,boost::shared_lock后的读操作代码可以被多个进程同时使用。但是boost::unique_lock后的写操作代码不允许被执行。
当boost::unique_lock锁定(即SetFields被执行)时,boost::shared_lock后的读操作代码被禁止,boost::unique_lock后的写操作代码只允许当前线程(或进程)执行,禁止其他线程(或进程执行)。

https://blog.csdn.net/daraemon418/article/details/7211693

类成员存放位置

声明类是不占内存空间的,但是实例化类就占空间了。另外如果类中有static 声明的变量,也就是静态变量,就占内存空间了,成员函数可以被看作是类作用域的全局函数,不在对象分配的空间里,只有虚函数才会在类对象里有一个指针,存放虚函数的地址等相关信息。
  成员函数的地址,编译期就已确定,并静态绑定或动态的绑定在对应的对象上。
  对象调用成员函数时,编译器可以确定这些函数的地址,并通过传入this指针和其他参数,完成函数的调用,所以类中就没有必要存储成员函数的信息。

类成员函数作为右值赋给函数指针

需使用以下方式,不加&号,则会报错,猜测原因:
类成员(非static成员)应该存放在栈区(类static成员在数据段)。类成员未被初始对象化,成员函数未跟对象绑定,使用Class::func的方式是找不到对应成员函数值。
而static成员在数据段,可以在类外直接赋值和读取

   void (T::* f_po1) (int a);
   f_po1 = &T::fun1;
   (t1.*f_po1)(11);
#include <iostream>

using namespace std;
class T {
    public:
        void fun1 (int a){ cout << "T::fun1" << a << endl;}
};

void fun2 (int a)
{
    cout << "fun2" << a << endl;
}

int main()
{
    void (T::* f_po1) (int a);
    void (* f_po2) (int a);

    //f_po1 = T::f; //报错,invalid use of non-static member function
    f_po1 = &T::fun1; //正确
    //T::fun1(2); 报错,需实例化才能调用成员函数
    f_po2 = fun2;
    f_po2(2);

    T t1;
    t1.fun1(1);
    (t1.*f_po1)(11); //实例化才可调用类成员函数

    T *t2 = new(T);
    t2->fun1(21);
    delete(t2);

    return 0;
}

结果:

fun22
T::fun11
T::fun111
T::fun121

#pragma omp parallel for是OpenMP中的一个指令,表示接下来的for循环将被多线程执行,另外每次循环之间不能有关系。示例如下:

int main(int argc, char* argv[])
{
#pragma omp parallel for  //后面是for循环
     for (int i = 0; i < 10; i++ )
     {
         printf("i = %d/n", i);
     }
     return 0;
}

这个程序执行后打印出以下结果:
i = 0
i = 5
i = 1
i = 6
i = 2
i = 7
i = 3
i = 8
i = 4
i = 9
for循环里的内容必须满足可以并行执行,即每次循环互不相干,后一次循环不依赖于前面的循环。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值