我在网上找到篇文章(《Windows多线程多任务设计初步》),其中讲到临界区的使用,文章中给了个例程,但用的是MFC,如下:
#include "afxmt.h"int array[10],destarray[10];
CCriticalSection Section;////////////////////////////////////////////////////////////////////////
UINT WriteThread(LPVOID param)
{
      Section.Lock();
      for(int x=0;x<10;x++)
           array[x]=x;
      Section.Unlock();
}UINT ReadThread(LPVOID param)
{
      Section.Lock();
      For(int x=0;x<10;x++)
           Destarray[x]=array[x];
      Section.Unlock();
}我用的编译器是devc++,不是vc,但我想试试,就查了MSDN改成下面的样子:
//试试临界区
#include <windows.h>
#include <process.h>
#include <iostream>using namespace std;int array[10], Destarray[10];CRITICAL_SECTION cs;//临界区 //为array赋值 
void WriteThread(PVOID p)
{
     EnterCriticalSection(&cs);//进入临界区 
     for(int x = 0; x<10; x++)
     {
             array[x] = x;
     }
     LeaveCriticalSection(&cs);//离开临界区 
} //将array中的值传给Destarray 
void ReadThread(PVOID p)
{
     EnterCriticalSection(&cs);
     for(int x = 0; x<10; x++)
     {
             Destarray[x] = array[x];
     }
     LeaveCriticalSection(&cs);
}int main()
{
    InitializeCriticalSection(&cs);//初始化临界区 
    _beginthread(WriteThread,0,NULL);
    _beginthread(ReadThread,0,NULL);
    DeleteCriticalSection(&cs);//删除临界区 
    for(int i = 0; i<10; i++)
    {
            cout<<array[i]<<" "<<Destarray[i]<<endl;
    }
    cout<<"完成"<<endl;
    cin.get();
    return 0; 
}开始时没有加入和临界区有关的那些代码(基本上就是有注释那些),程序编译通过,显示的数字次序是乱的。之后我加入了和临界区有关的代码,编译也通过了,但是运行时windows(我的是XP)弹出了对话框:
“thread3.exe - 应用程序错误
  "0x77f51c96"指令引用的"0x00000010"内存。该内存不能为"written"。
   要终止程序,请单击“确定”。
   要调试程序,请单击“取消”。”
 还有一个发送错误报告的对话框。
我又进行了单步调试,每次程序在不同的地方会弹出个对话框:
“Warning
         程序产生一个访问违例(段异常)"
点OK后接着再按单步什么的就没反应的,但没死机,也没碰到蓝屏什么的。另外在单步调试时显示的值全是0.请各位高手帮忙看看是不是我的程序出什么错了?谢谢!

解决方案 »

  1.   

    有问题, 你的程序会有3个线程, main, WriteThread和ReadThread, 你只考虑了WriteThread和ReadThread的互斥, 确没有考虑main线程要等待WriteThread和ReadThread全完成后, 才能DeleteCriticalSection.int main()
    {
        HANDLE h[2];
        InitializeCriticalSection(&cs);//初始化临界区 
        h[0] = (HANDLE)_beginthread(WriteThread,0,NULL);
        h[1] = (HANDLE)_beginthread(ReadThread,0,NULL);    // 等待2个线程结束
        WaitForMultipleObjects(sizeof(h), h, TRUE, INFINITE);    DeleteCriticalSection(&cs);//删除临界区 
        for(int i = 0; i<10; i++)
        {
                cout<<array[i]<<" "<<Destarray[i]<<endl;
        }
        cout<<"完成"<<endl;
        cin.get();
        return 0; 
    }
      

  2.   

    谢谢您,我照您的改了,可还是出错,但改成下面这样,把DeleteCriticalSection()放到输出后面运行时就没有出现什么内存错误,可输出的结果还是不对。
    //试试临界区
    #include <windows.h>
    #include <process.h>
    #include <iostream>using namespace std;int array[10], Destarray[10];CRITICAL_SECTION cs;//临界区 //为array赋值 
    void WriteThread(PVOID p)
    {
         EnterCriticalSection(&cs);//进入临界区 
         for(int x = 0; x<10; x++)
         {
                 array[x] = x;
         }
         Sleep(100);
         LeaveCriticalSection(&cs);//离开临界区 
    } //将array中的值传给Destarray 
    void ReadThread(PVOID p)
    {
         EnterCriticalSection(&cs);
         for(int x = 0; x<10; x++)
         {
                 Destarray[x] = array[x];
         }
         Sleep(10);
         LeaveCriticalSection(&cs);
    }int main()
    {
        HANDLE h[2];
        InitializeCriticalSection(&cs);//初始化临界区 
        h[0] = (HANDLE)_beginthread(WriteThread,0,NULL);
        h[1] = (HANDLE)_beginthread(ReadThread,0,NULL);
        WaitForMultipleObjects(sizeof(h),h,TRUE, INFINITE);
        for(int i = 0; i<10; i++)
        {
                cout<<array[i]<<" "<<Destarray[i]<<endl;
        }
        DeleteCriticalSection(&cs);//删除临界区 ,挪到这里就没有内存错误。
        cout<<"完成"<<endl;
        cin.get();
        return 0; 
    }运行的结果一次和一次不一样,下面是其中一次:
    0 0
    0 0
    0 0
    3 0
    4 0
    5 0
    6 0
    7 0
    8 0
    9 0
    完成
    而我设想的结果好象应该是两列数字都是从0到9排下来。谢谢!
      

  3.   

    晕,忘了昨天又在两个线程里加了Sleep,如果把Sleep注释掉两列数字都一样了,但还不是按顺序排列,像下面这样:
    0 0
    0 0
    0 0
    3 3
    4 4
    5 5
    6 6
    7 7
    8 8
    9 9
    完成
      

  4.   

    WaitForMultipleObjects(sizeof(h),h,TRUE, INFINITE);
    改为
    WaitForMultipleObjects(2,h,TRUE, INFINITE);sizeof(h)!=2  ==8
      

  5.   

    谢谢seasol(海子@CSDN助手:http://www.cuteie.com/other.asp) , 我疏忽了.