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循环里的内容必须满足可以并行执行,即每次循环互不相干,后一次循环不依赖于前面的循环。