�ദ�����������߳�ͬ���ĸ߼�����

����

baiy.cn

��

��Ϊ��C++�����淶��ָ�����е�һ��С�ڣ�������Ҫ������ C/C++ ���������ԱȽϽ��ܵģ�SMP �����µĶ��߳�ͬ�����⡣֮���Գ�֮Ϊ���߼����⡷����Ϊ����Ԥ�ڵĶ����Ѿ��߱����ź�����������������������ԭ�Ӳ����;�̬�����ȷ����ı���֪ʶ�����ǽ��Դ�Ϊ������ʼ�����������Ը߼�һ�������⣺

��

ԭ�Ӳ����� volatile �ؼ���

volatile �ؼ���ȷʵ��ԭ�Ӳ�����Ԥ��������������֮���Ĺ�ϵ�������ܶ�����������ô������

C/C++ �е� volatile �ؼ����ṩ�����±�֤��

  1. ������Ϊ volatile �ı������е��κβ��������ᱻ�Ż���ȥ������ʹ��������û�����壨���磺�������ζ�ij����������ͬ��ֵ������Ϊ�����ܱ�ij���ڱ���ʱδ֪���ⲿ�豸���̷߳��ʡ�
  2. ������Ϊ volatile �ı������ᱻ�������Ż����Ĵ����У�ÿ�ζ�д��������֤���ڴ�(��������)�����ɡ�
  3. �ڲ�ͬ����ʽ�ڵĶ��� volatile �������IJ���˳�򲻻ᱻ�Ż���������������������֤���� volatile ������ sequence point ֮���ķ���˳�򲻻ᱻ�Ż��͵�������

volatile *��* �ṩ���±�֤

  1. volatile ��������֤��д������������ԭ���ԡ�
  2. volatile ��������֤�������еĶ�д����ֱ�ӷ��������ڴ档�෴��CPU �ᾡ��������Щ��д���������� L1/L2 �� cache �ϡ����ǣ�
    1. ������һ��δ���еĶ�������
    2. ���м����� cache ���ѱ�����Ϊͨ��ʽд��write through����
    3. Ŀ����ַΪ non-cacheable ������Ҫ�������豸ӳ�䵽�ڴ���ַ�ռ���ͨ�Žӿڡ����磺�����İ��ػ��������Կ������Դ桢WatchDog �Ĵ����ȵȣ���
  3. ����������֤������Ŀ����ʱ������ volatile �����ķ���˳�򣬵�ͨ��������֤�ñ������ܴ������� out-of-order ����Ӱ�졣ĿǰΨһһ����֪�������ǰ��ڣ�IA64������������ VC�������� IA64 Target ʱ��VC ���Զ������� volatile ����֮�������ڴ����ϣ��������ģ��Ա�֤����˳�򡣵� ISO ��׼��δҪ��������ʵ�����ƻ��ơ�ʵ���ϣ�������������������������ƽ̨�� VC��Ҳ��û�����Ʊ�֤��Ҳ����˵��ͨ����Ϊ volatile ������֤�����ڴ������ϵ�ִ��˳����������Ҫ���Ƶı�֤������ԱӦ���Լ�ʹ���ڴ����ϲ�����

��ԭ�Ӳ���Ҫ���������±�֤��

  • ��ԭ������ '����-����-д��' ����������ԭ�ӵģ������϶�������֮ǰ���κ��������������߳̾��޷����ʸ�ԭ������
  • ԭ�Ӳ������뱣֤����һ���ԡ������ڶദ���������У�ԭ�Ӳ���Ҫͬʱ�������д������ϵĸ��� cache ֮�䡢�Լ��������������ķ���һ���ԡ�

�ɼ���ʹ�� volitale �ؼ��ֲ������Ա�֤������ԭ�����塣volitale �ؼ��ֵ���Ҫ����Ŀ����֧�� C/C++ �������ڴ�ӳ���豸����ͨ�š����Ⲣ����˵ volitale �ؼ��ֶ�ԭ�Ӳ���û���κΰ�����

  • ����һ��������Ϊ volitale ���͵�ԭ������˵����������д��������ԭ�ӵģ��������ṩ�˱�Ҫ�� cache һ���Ա�֤����ô��ȡ��ԭ����ʱ�Ͳ����ٴζ�����������

    ������Ϊ volitale �ؼ��ֱ�֤�˶Ըñ����Ķ������������ڵ�ǰ CPU cache �����ɵģ������ñ������ᱻ�Ż����Ĵ����У�������ͬʱ��ֻҪ��ǰ�����ܹ���֤������������ cache ֮�䣬�Լ� cache ������֮���ķ���һ���ԡ���ô�ö��������������滹�ǵ�ǰϵͳ������һ���������� cache �Ϸ����������Ķ���һ�µ����ݡ�

    �����volitale �ؼ�������ԭ������д������һ��ʵ����һ�����͵Ķ���/д��ͬ��ģ�ͣ�����д������ cache ͬ������֤��ԭ�ӡ����������ɣ������������Ա�������ʵ�֡���Ҳ�� Windows API ��û���ṩ���� 'AtomicLoad' ʽ����������ԭ����

    ��Ȼ�����ﻹ��һ�������ĸ������������� CPU �����ܹ���һ�������ж�������ԭ��������������ͨ�����Ժ��ԣ���Ϊ���� CPU λ������������ͨ���޷���ʵ�ֳ�������ԭ�������͡�

�ڴ����Ϻ� Acquire��Release ����

�ڴ����ϣ�Memory barrier, membar�� �������� CPU ����ִ���Ż����ڴ�����˳����Ӱ�죬ͨ�����ڱ�֤���������������ʵ��߼�˳�����ڴ����Ϸ�Ϊ���¼��֣�
  • ȫ�������壺ȫ�����߼��ϵIJ�������Ϊ��'����&˫��ͬ��'�����������ڸò���ִ��ǰ���ڴ�����ָ���������������ָ����ִ�У������ڸò���ִ�к����ڴ�����ָ��Ҳ���ñ�������������ָ������ǰִ�С�ȫ���������������ֱ��壺�����Ϻ�д���ϡ������ֱ��嶼��˫�����ϣ�ֻ���������Ͻ����� load ������ִ��˳�򣬶����� store ������˳���������κ����ơ��෴��д������������ store ������ִ��˳����
    ��
  • Acquire ���壺Acquire �����߼��ϵIJ�������Ϊ '����-����ͬ��'��Acquire ����Ҫ�����к����ڴ����ʶ����ñ������������ò���ǰִ�С�Acquire ���Ͼ���������ʵ�ֻ�����������ͨ�� Acquire ����֮��������Ϊ�ٽ����������ķ�����ͬ����֤���ٽ����ڵ��ڴ����ʲ���������ǰ�� Acquire ����֮ǰ���У��������� Acquire ����֮ǰ���ڴ����ʲ����������Ƴٵ��ٽ�����ִ�С�
    ��
  • Release ���壺Release �����߼��ϵIJ�������Ϊ '��ǰͬ��-����'��Release ����Ҫ������ǰ���ڴ����ʶ����ñ������������ò�����ִ�С�Release ���Ͼ���������ʵ�ֻ�����������ͨ�� Release ����֮ǰ������Ϊ�ٽ�������ǰ�ķ�����ͬ����֤���ٽ����ڵ��ڴ����ʲ��������Ƴٵ� Release ����֮�����У��������� Release ����֮�����ڴ����ʲ�����������ǰ���ٽ�����ִ�С�
    ��
  • ���������壺��Ϊ���������ڴ����ϣ��߼��ϵIJ�������Ϊ��'����'��

ȫ�����������÷�Χ���㣬�κ�ʹ�������������ϵij��϶����԰�ȫ�滻Ϊȫ���ϲ�������������ȫ�����������̶��Ͻ����˴�����������ִ�������� ��������Ч�����͵��ڴ����ϲ�����Acquire ���ϱ�֤�����ڴ�����һ���ڵ�ǰ�������Ϻ����У���Ҫ����ʵ�ֻ��������ź���������������Release ���ϱ�֤ǰ���ڴ�����һ���ڲ�����ʼǰִ�����ϡ���Ҫ����ʵ�ֻ��������ź����Ľ���������������������ȫ������ CPU ������ִ���Ż���Ч�����ߣ� �ɹ㷺���������ü����ȴ󲿷���Ҫʹ��ԭ���������ij��ϡ�

�ο����ϣ�

��

ȫ�ֶ�����ʼ��ʱ���̰߳�ȫ�Ժ��໥����������

C++ ��֤ȫ�ֱ����ڽ���������ʱ�������Σ����ձ��뵥Ԫ�ڵĶ���˳�򣩵س�ʼ����C++ ��֤ÿ��ȫ�ֶ����ڽ��̼���ʱ������һ�Σ��ڽ��̽���ʱ�����빹���෴��˳��������һ�Ρ����ǣ�C++ ������֤�ڲ�ͬ���뵥Ԫ�ڶ�����ȫ�����ᰴ�ճ���ԱԤ�ڵ�˳����ʼ����

���ң������û�������ijЩ�ڹ���ʱ�ᴴ�����������̵߳�ȫ�ֶ�������ô������Ҳ�Dz���ȫ�ġ��������Σ���ȫ��������ʱ�������߳���һ���ܲ��õı���ϰ�ߡ���Ϊ��ʱ�û������͵��������п��ܻ��кܶ�ȫ�ֱ���û�л����ڱ���ʼ����C++ ����֤��ͬ���뵥Ԫ�ڵ�ȫ������ʼ��˳�򣩣����̺߳ܿ��ܻ�ֱ�ӻ����ӵط��ʵ�δ��ʼ����δ��ȫ��ʼ����ȫ�ֱ�����

���⣬��Ҫȷ���ڲ�ͬ���뵥Ԫ�ڶ�����ȫ��������Ԥ�ڵ�˳����ʼ����һ���鷳�����顣�� VC��SUN CC �ȱ������ṩ�� init segment Ԥ����ѡ����֧�֣���ʱ�����ȼ��ϸߵĶ��ڶ�����ȫ������������ȫ�����ȳ�ʼ�������� init segment ���ṩ��һ�ֳ�ʼ��˳���Ĵ������ַ�ʽ������ GCC �Ⱥܶ��������в�֧�ָ�ѡ�

������Ҫ����ϸ�ؿ���ȫ������������ϵ��������Ҫ�ڲ�֧�� init segment ָ���ı��뻷���п���ȫ������ʼ��˳�򣬾���Ҫʹ��һЩ�ر��ļ��ɡ����磺������ͬһ���뵥Ԫ�ڶ�����ȫ�������ǰ����䶨��˳����ʼ������Ϊ�����ǿ�����������ij��ȫ���� 'G' ��ͷ�ļ� "G.h" �ж���һ����̬ȫ���� 'S' ��ʹ�� static �ؼ��ֻ������ռ䣩��������Ϊÿ�������� "G.h" �ı��뵥Ԫ��������һ����̬ȫ���� 'S'������ 'G' �� #include "G.h" ֮���ſɼ����������ж�ȫ���� 'G' �ķ��ʶ������� 'S' ������֮����Ҳ����˵����̬ȫ���� 'S' һ������ 'G' ������ǰ���졣����ֻҪ�� 'S' �Ĺ��캯������ʽ�����ɶ� 'G' �ij�ʼ������ȷ����ʼ��˳�����������Թ�ϵ����ȷ�ؽ�����

������һЩ�� 'S' Ӧ�����乹�캯����ά��һ�����ξ�̬������Ϊ���ü�����ȷ�����ڵ�һ�� 'S' ���󱻹���ʱ���ɳ�ʼ���Ϳ����ˡ�

������ʹ�����ּ���ʱ����Ȼ��Ҫע�����¼������⣺

  • ��Ϊÿһ�������� "G.h" �ı��뵥Ԫ����һ����̬���� 'S'����Ȼ 'S' ͨ���������κ����ݳ�Ա����Ҳ��һ���̶��������˽��̼���ʱ�Ŀ������ر�������Դ���޵Ļ������磺Ƕ��ʽӦ�ã������뵥Ԫ�ܶ��ij��ϡ�
    ��
  • �޷���������������ϵ�����磺ȫ�ֶ��� A ��ʼ��ʱ��������һ�����뵥Ԫ�ж�����ȫ���� B���� B �ڳ�ʼ��ʱ��������ȫ���� C����ô���ּ���ֻ�ܱ�֤��ʼ��˳�򲿷���ȷ�����磺���Ա�֤ B �� A ֮ǰ��ʼ�������޷���֤ C �� B ֮ǰ��ʼ������Ϊ��һ����ʵ���ϴ����� CRT �Բ�ͬ���뵥Ԫ�ij�ʼ��˳����������ʹ�ô˼���ǿ�Ƴ�ʼ�� B ʱ���� B ֮ǰ���壨ͬһ���뵥Ԫ�ڵģ�ȫ����������δ����ʼ����
    ��
  • �޷������ֲ���̬������ȫ����֮����������ϵ������ij���� 'func()' �ж�����һ���ֲ���̬���� 's_obj'���ö����ij�ʼ�������� 'func()' ���ڱ��뵥Ԫ�ڵ�ij��ȫ�ֱ��������ڱ�����������֤�ֲ���̬������ȫ�ֱ���֮���ij�ʼ��˳�򣨼�ʹ��ͬһ���뵥Ԫ�ڣ����������� 'func()' �������ڵı��뵥Ԫ�е�ȫ�������ɳ�ʼ��֮ǰ�ͱ����ã���ô����������Ԥ���Ľ������������������ķ���ͨ���ǽ� 's_obj' ��������ȫ����Ҳ����һ�������У�ʹ����Ϊ���������ء��ľֲ���̬������������������һ��С�ڣ�

��

�ֲ���̬������ʼ��ʱ���̰߳�ȫ������

C++ ��׼��֤�ֲ���̬�������ڵ�һ��ʹ��ʱ����ʼ��������������ʼ���෴��˳���ڽ��̽���ʱ���١����ǣ�C++ ����֤�ֲ���̬������ʼ���Ķ��̰߳�ȫ�ԡ�ʵ���ϣ���������������ʹ���������µļ���ʵ�ֱ��ؾ�̬������ʼ���ģ�
��
�û�������
void func(void)
{
    static int s_nMyVar = MyCalcAlgorithm();
    // ...
}

���������ɵĴ�����
void func(void)
{
    static int bCompilerInitFlag;  // ��ʼ������
    static int s_nMyVar;
    if (FALSE == bCompilerInitFlag)
    {
        bCompilerInitFlag = TRUE;
        s_nMyVar = MyCalcAlgorithm();
    }
    // ...
}

���������ӿ�֪������ func ��Ҫ�����ڶ��̲߳����Ļ����У������ܻ��������¼��־�̬������

  1. ʹ��δ����ʼ���� s_nMyVar���߳� A ִ�� bCompilerInitFlag = TRUE�������� MyCalcAlgorithm ��δ���أ���ʱ�߳� B �ж� FALSE == bCompilerInitFlag Ϊ false ������Ϊ s_nMyVar �ѳ�ʼ�����ϣ���

  2. s_nMyVar ���ظ���ʼ�����߳� B ���߳� A ִ�� bCompilerInitFlag = TRUE ǰ������ FALSE == bCompilerInitFlag �жϣ���

  3. ���� s_nMyVar �ij�ʼ����Ϊ����һ��ԭ�Ӳ��������磬s_nMyVar ��һ���ṹ�壩�����п��ܳ���δ��ȫ��ʼ���� s_nMyVar ��ʹ�õ�����������һ�����ƣ���

���ڷ� POD ���ͣ����������Ӹ��ӣ�

�û�������
void func(void)
{
    static CMyClass s_iMyObj;
    // ...
}

���������ɵĴ�����
void DestroyMyObj(void) // ������������
{
    `void func(void)::'s_iMyObj.~CMyClass();
}

void func(void)
{
    static int bCompilerInitFlag;  // ��ʼ������
    static CMyClass s_iMyObj;
    if (FALSE == bCompilerInitFlag)
    {
        bCompilerInitFlag = TRUE;
        s_iMyObj.CMyClass(&s_iMyObj); // ���ù��캯��
        atexit(&DestroyMyObj);        // ���˳�����ʱ������������
    }
    // ...
}

���Կ�������ʱ����ǰ���ᵽ�ĸ��־�̬�����⣬�����ܳ��� s_iMyObj �Ĺ��캯�����������������ε��õ����⡣

���������ԶԳ�������Ҫ�����ǾͿ���ʹ��һ�ּ򵥵ķ�ʽ����֤�ֲ���̬������ʼ��ʱ�Ķ��̰߳�ȫ�ԣ�

void func(void)
{
  CFastSessionLock flk(fmxLock); // ÿ�η��ʺ���������

    static int s_nMyVar1 = MyCalcAlgorithm1();
    static int s_nMyVar2 = MyCalcAlgorithm2();
    // ...
}

���� fmxLock ���Կ�����һ�����������󣬶� CFastSessionLock ����һ������ RAII ������ Sentry �ࣨ�ڹ���ʱ����������ʱ��������

���ߣ�������ʼ�����ط�Ҫ�ӳٵ��û���һ�ε��ô˺���ʱ�Ž��С����ǾͿ���ֱ�ӽ��ֲ���̬����������ȫ�ֱ�������̬���Ǿ�̬���ɣ���������Ҫ���Ʊ����������򣬿���ʹ��һ��ȫ����λ�����ɽ�������ʱ�ij�ʼ��������

namespace {
    class CLocalStaticInitializer
    {
    public:
        CLocalStaticInitializer()
        {
            func(); // ȷ���ڽ�������ʱ���� func �����б��ؾ�̬�����ij�ʼ��
        }
    };
    const CLocalStaticInitializer sg_initLocalStatics;
}

ǰ���Ѿ����������ֲ���̬������ͬ��C++ ��֤ȫ�ֱ����ڽ���������ʱ������ͬһ�����뵥Ԫ�ڶ�����ȫ�����ᰴ���䶨��˳�������εس�ʼ����

���⣬ʹ�����泣����ʼ��һ�����ؾ�̬ POD �������̰߳�ȫ�ġ�ʵ���ϣ�������ʼ���������ڳ�����һ��ִ�е��ñ�������������ʱ�Ž��еģ������ڳ�������ʱ��ֱ�Ӵ�ӳ���ļ��ڵ����ݶ��м����ˡ�������һ���� POD �����������Ƿ�ʹ�ñ���ʱ��֪�ij����������г�ʼ��������������ҪΪ�����ɵ��ù��졢���������Ĵ����ͳ�ʼ����־���������磺

void func(void)
{
    static int s_nMyVar1 = 15; // OK
    static int s_nMyVar2 = MyCalcAlgorithm(); // ���У����DZ���ʱ��֪�ij���

    static BYTE s_gbMyArray[3] = {1, 2, 3}; // OK

    struct MY_POD_TYPE
    {
        int a, b;
        const char* c;
    };
    static MY_POD_TYPE iMyPodData = { 10, 20, "30" }; // OK

    static std::string s_str = "123"; // ���У���ʹʹ�����泣����ʼ��һ���� POD ��
                                      // ���� ��������Ȼ��Ҫ���ɳ�ʼ����������Ӧ��
                                      // ־����
    // ...
}

���� POD ���ͣ�һ�ָ��õĽ��������ǣ��������ò���ϵͳ���ؽ���ʱ�������ݶ���ȫ����ʼ�������ԣ�C++ ��׼����ȷ�涨�ˣ����о�̬��Ա�����������ݶΣ��ڽ��̼���ʱ������ "zero-initialized"���������ݶ����㶯�����ڲ���ϵͳ���ؽ���ӳ��ʱ�����ɵģ���ʱ�����̶߳���û�б��������κ��û����붼û�п�ʼִ�У����Բ����ڶ��̰߳�ȫ�����⡣���磺

int func(void)
{
    static int s_nMyVar; // s_nMyVar �ڽ���ӳ������ʱ�ѱ���ʼ��Ϊ 0�� ������
                         // ����ҪΪ�������κη�װ�����ͱ�־����
    // ...
    return s_nMyVar;
}

ʵ���ϣ�ǰ���ᵽ�ģ��������Զ����ɵ� "bCompilerInitFlag" ���DZ������������������������ɳ�ʼ���ġ�

���ý������ݶ���ӳ������ʱ���������ԣ�����ʹ��һ�������������ǾͿ����ڼ�������ʧ�����Ե�ǰ���±�֤���Ȿ�ؾ�̬ POD ������ʼ��ʱ���̰߳�ȫ����

int func(void)
{
    static int s_nMyVar;
    if (0 == s_nMyVar)
    { CFastSessionLock flk(sg_fmxLocalStaticVarInit); // �ϻ�����

        if (0 == s_nMyVar) // �ж��ڵȴ�������ʱ�������߳��Ƿ������ɳ�ʼ��
        {
            s_nMyVar = MyCalcAlgorithm();
        }
    }
    return s_nMyVar;
}

�������ӱ�֤�� s_nMyVar ��ʼ��ʱ�Ķ��̰߳�ȫ�ԣ�ͬʱֻ�� s_nMyVar ��δ������ʼ��ʱ�����˲������òŻ��ϻ������������޶ȵر�֤�˲���Ч�ʡ�

�� POD ���͵����������Ը��ӡ� ��Ϊ���������ǻ����ɵ��ù��캯��������������ѹ�������˳��ڣ�atexit���Ĵ��룬������Ҫ��ά�ֲ����Ե�ͬʱ��֤����ʼ��ʱ���̰߳�ȫ�ԣ������� POD �����ͱ�����������������

  1. �ܹ����ý��̼���ʱ�����ݶ��������ԣ��������������������л��඼�ܹ���ȷ��ʶ���ʹ����������ݳ�Ա��Ϊȫ 0 ֵʱ�����Σ���

  2. ��֤�乹�캯�������������ɵij�ʼ�����벢�����ظ�����ʱ���������κθ����ã�ͨ����Ҫ������һ��ʵ�֣���

  3. ��֤�����������ڽ����˳��ڱ�˳�򣨷Dz��������ظ�����ʱ���������κθ����ã�

  4. ����ʼ�����������ڼ�����ʼ���Ƿ����ɵIJ�����˵����һ��ԭ�Ӳ������⼴���������еĵ�һ�� if ���䷵�� false ʱ��s_thMyVar ���뱣֤�Ѿ���ʼ�����ϣ�������������ʼ����һ����״̬��

�ź����ǣ��󲿷����������඼�޷�ͬʱ�������� 4 ��������Ϊ�ˣ����ǿ���ʹ��һ�������������и��������磺

const CMyClass& func(void)
{
    typedef CTmpHandle< CMyClass > THMYCLASS;

    static THMYCLASS s_thMyObj(DontInit); // DontInit ռλ��������ʼ����Ա
    if (!s_thMyObj)
    { CFastSessionLock flk(sg_fmxLocalStaticVarInit); // �ϻ�����

        if (!s_thMyVar) // �ж��ڵȴ�������ʱ�������߳��Ƿ������ɳ�ʼ��
        {
            s_thMyObj = new CMyClass;
        }
    }
    return *s_thMyObj;
}

���������Լ򵥵���Ϊ CTmpHandle ��һ������ "std::auto_ptr" ������ָ��ģ���࣬����һ��ָ���ͳ�Ա 'ptr'��"DontInit" ռλ����ʾ����ʱ�����κζ��������������캯���Ķ��β������ý����൱�ڵ����˿պ��������������κβ���Ӱ�졣�� CTmpHandle ������������������������ "delete ptr; ptr = NULL;" ��Ϊ��ͻ�����⣬����û�к����� delete ʱ���������׳��쳣�������������ٺ��� 'ptr' ��Ϊ 'NULL' ��֤���ڳ����˳������еض��ε��������������������κθ����á��������ij�ʼ����������һ������������������ֻ�� s_thMyObj ��δ������ʼ��ʱ�����˲������òŻ��ϻ����������������޶ȵر�֤�˲���Ч�ʡ�

˳����һ�£������е� 's_thMyObj = new CMyClass;' ������ʵ����һ��ָ�븳ֵ������'s_thMyObj.ptr = new CMyClass'���������� '!s_thMyObj' ���� 'NULL != s_thMyObj.ptr' ��ȫ��Ч����������Ҳ�������ϵ������������ġ�����ʼ�����������ڼ�����ʼ���Ƿ����ɵIJ�����˵����һ��ԭ�Ӳ�������Ӧ��ע�⵽���˴��ġ�ԭ�Ӳ������뱾�ĵ�һ����������Ӳ�������IJ�����һ�����

��

 

��Ȩ���� (C) 2004 - 2019, ���� (baiy.cn). ��������Ȩ��.
Copyright (C) 2004 - 2019, Bai Yang (baiy.cn). All Rights Reserved.

XMR ����: 851299mKHBZhEEkQfbVBM6NgvUbACdeBoNxqppeuUgfL9vi3f1JpXGWAfBThKMK6XT38wpUU9vPC8AYzxQUooGxt2wi38D7

 

 

 

 

 

��

��