本人想知道 为啥多线程在对待局部类对象和局部变量的时候会有区别 本人编译器为vs2005 例一:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;CRITICAL_SECTION cs;
void PlusSection(LPVOID lp);DWORD WINAPI SectionThread1(LPVOID lp)
{
int a = 0;

while(true)
{
PlusSection(&a);
::Sleep(200);
}

return 0;
}DWORD WINAPI SectionThread2(LPVOID lp)
{
int b = 0; while( true )
{
PlusSection(&b);
::Sleep(200);
} return 0;
}void PlusSection(LPVOID lp)
{
::EnterCriticalSection(&cs);
int* np = static_cast<int*>(lp); if( np != NULL )
{
cout<<++(*np)<<endl;
cout<<"this is ++(*np)"<<endl;
cout<<--(*np)<<endl;
cout<<"this is --(*np)"<<endl;
} ::LeaveCriticalSection(&cs);
}int _tmain(int argc, _TCHAR* argv[])
{
::InitializeCriticalSection(&cs);
::CloseHandle(::CreateThread(NULL, 0, SectionThread1, NULL, 0, 0));
::CloseHandle(::CreateThread(NULL, 0, SectionThread2, NULL, 0, 0));

int i = 1; while(true)
{
cin>>i; if(!i)
{
::DeleteCriticalSection(&cs);
break;
}
} return 0;
}以上例子 两个线程可以同步执行 没有任何问题!!!!!绝对的没有问题!!!!!!!!!!那为啥下面的例子就有问题了呢  下面例子中 两个线程不能同步执行 例二:
//main.cpp#include "stdafx.h"
#include "CSection.h"
#include <iostream>
using namespace std;
DWORD WINAPI Thread1(LPVOID lp);
DWORD WINAPI Thread2(LPVOID lp);
int nStopThread = 1;int _tmain(int argc, _TCHAR* argv[])
{
::CloseHandle(::CreateThread(NULL, 0, Thread1, NULL, 0, 0));
::CloseHandle(::CreateThread(NULL, 0, Thread2, NULL, 0, 0)); while(true)
{
cin>>nStopThread;

if(!nStopThread)
{
break;
}
} return 0;
}DWORD WINAPI Thread1(LPVOID lp)
{
MYSection mySection; while(true)
{
if(!nStopThread)
{
return 0;
} mySection.PlusItself();
::Sleep(200);
}
}DWORD WINAPI Thread2(LPVOID lp)
{
MYSection mySection; while(true)
{
if(!nStopThread)
{
return 0;
} mySection.PlusItself();
::Sleep(200);
}
}//CSection.h#ifndef HEADER_SECTION
#define HEADER_SECTION
#include <windows.h>class MYSection
{
public:
MYSection();
~MYSection();
void PlusItself();
private:
int m_nCount;
};#endif //HEADER_SECTION//CSection.cpp
#include "stdafx.h"
#include "CSection.h"
#include <iostream>
using namespace std;CRITICAL_SECTION cs;MYSection::MYSection():m_nCount(0)
{
cout<<"constructor"<<endl;
::InitializeCriticalSection(&cs);
}MYSection::~MYSection()
{
cout<<"destructor"<<endl;
::DeleteCriticalSection(&cs);
}void MYSection::PlusItself()
{
::EnterCriticalSection(&cs);
cout<<++m_nCount<<endl;
cout<<"this is ++"<<endl;
cout<<--m_nCount<<endl;
cout<<"this is --"<<endl;
::LeaveCriticalSection(&cs);
}上面 俩线程有点打架 不能同步执行 这两个例子的不同就是 例一中的两个线程函数中是局部变量 例二中的两个线程函数中是局部类对象 windows对待变量和对象是不同的态度吗??顺便问一下 为啥不能把Sleep()放在LeaveCriticalSection之前呢?????

解决方案 »

  1.   

    第二个 InitializeCriticalSection 执行了2次。
      

  2.   

    #include <windows.h>
    class MYSection
    {
    public:
    MYSection(int m);
    ~MYSection();
    void PlusItself();
    private:
    int m_nCount;
    };#include <iostream>
    #include "CSection.h"
    using namespace std;
    extern CRITICAL_SECTION cs;
    MYSection::MYSection(int m):m_nCount(m)
    {
    }
    MYSection::~MYSection()
    {
    }
    void MYSection::PlusItself()
    {
    ::EnterCriticalSection(&cs);
    cout<<++m_nCount<<"this is ++"<<endl;
    cout<<--m_nCount<<"this is --"<<endl;
    ::LeaveCriticalSection(&cs);
    }
    #include <iostream>
    #include "CSection.h"
    using namespace std;
    DWORD WINAPI Thread1(LPVOID lp);
    DWORD WINAPI Thread2(LPVOID lp);
    int nStopThread = 1;
    CRITICAL_SECTION cs;
    int main(int argc, TCHAR* argv[])
    {
    ::InitializeCriticalSection(&cs);
    ::CloseHandle(::CreateThread(NULL, 0, Thread1, NULL, 0, 0));
    ::CloseHandle(::CreateThread(NULL, 0, Thread2, NULL, 0, 0));

    while(true)
    {
    cin>>nStopThread;

    if(!nStopThread)
    {
    ::DeleteCriticalSection(&cs);
    break;
    }
    }

    return 0;
    }DWORD WINAPI Thread1(LPVOID lp)
    {
    MYSection mySection(1);

    while(true)
    {
    if(!nStopThread)
    {
    return 0;
    }

    mySection.PlusItself();
    ::Sleep(200);
    }
    }DWORD WINAPI Thread2(LPVOID lp)
    {
    MYSection mySection(2);

    while(true)
    {
    if(!nStopThread)
    {
    return 0;
    }

    mySection.PlusItself();
    ::Sleep(200);
    }
    }
      

  3.   

    #include <iostream>
    #include "CSection.h"
    using namespace std;
    DWORD WINAPI Thread1(LPVOID lp);
    DWORD WINAPI Thread2(LPVOID lp);
    int nStopThread = 1;
    CRITICAL_SECTION cs;
    int main(int argc, TCHAR* argv[])
    {
    ::InitializeCriticalSection(&cs);
    ::CloseHandle(::CreateThread(NULL, 0, Thread1, NULL, 0, 0));
    ::CloseHandle(::CreateThread(NULL, 0, Thread2, NULL, 0, 0));

    while(true)
    {
    cin>>nStopThread;

    if(!nStopThread)
    {
    ::DeleteCriticalSection(&cs);
    break;
    }
    }

    return 0;
    }DWORD WINAPI Thread1(LPVOID lp)
    {
    MYSection mySection(1);

    while(true)
    {
    if(!nStopThread)
    {
    return 0;
    }

    mySection.PlusItself();
    ::Sleep(200);
    }
    }DWORD WINAPI Thread2(LPVOID lp)
    {
    MYSection mySection(2);

    while(true)
    {
    if(!nStopThread)
    {
    return 0;
    }

    mySection.PlusItself();
    ::Sleep(200);
    }
    }#include <iostream>
    #include "CSection.h"
    using namespace std;
    extern CRITICAL_SECTION cs;
    MYSection::MYSection(int m):m_nCount(m)
    {
    }
    MYSection::~MYSection()
    {
    }
    void MYSection::PlusItself()
    {
    ::EnterCriticalSection(&cs);
    cout<<++m_nCount<<"this is ++"<<endl;
    cout<<--m_nCount<<"this is --"<<endl;
    ::LeaveCriticalSection(&cs);
    }
    #include <windows.h>
    class MYSection
    {
    public:
    MYSection(int m);
    ~MYSection();
    void PlusItself();
    private:
    int m_nCount;
    };
      

  4.   

    离开临界区线程睡眠,让出cpu,其他线程执行,若在LeaveCriticalSection()之前,线程1睡了,但线程2也得不到执行,因为钥匙在线程1那。(虽然他在睡觉)
      

  5.   


    ++
    这样就浪费了cpu的时间了。效率变低了。
      

  6.   

    写个lock类,在构造函数中进入cs,惜构时退出