我的程序是这样的,有一个线程A负责每10秒钟采集一组数据,线程B和线程C读取采集到的数据后分别负责网络传输和存入数据库。我想采用共享内存的方式处理。struct  DATA
{
   WORD val[100];
};
CEvent beginEvent;   //建立自动事件对象,初始为未发信状态// 线程A 中建立消息队列,将值写入共享内存块中UINT Thread_A(LPVOID lpVal)
{
//建立共享内存
DATA *data=NULL;
HANDLE hFileMapping;
hFileMapping=::CreateFileMapping(0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(DATA),"Share");
        data=(DATA *)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
        
        ...
        //消息队列
        int nTimerID=SetTimer(NULL,1,10000,NULL);
        while (1)
{
if(GetMessage(&msg,NULL,NULL,NULL))
{
                   case WM_TIMER:   //定时器消息  10秒触发一次
{
                                WORD  dVal[100];
...
                                ...
for (int i=0;i<100;i++)
{
  data->val[i]=dVal[i];  //给共享内存 赋值
} beginEvent.SetEvent();   //设置事件为发信状态
}
break;
                   
                   ...
                }           }  //  while (bRun)
       
         //放在这儿对吗?
         UnmapViewOfFile(dataVal);
 CloseHandle(hFile);         return 0;
}//线程B和C也是每隔10钟就读取共享内存中的值,然后分别进行处理。B和C都要在线程A之后进行处理,所以用事件对象beginEvent进行同步UINT Thread_B(LPVOID lpVal)
{
        
        ...
        //消息队列
        int nTimerID=SetTimer(NULL,1,10000,NULL);
        while (1)
{
if(GetMessage(&msg,NULL,NULL,NULL))
{
                   case WM_TIMER:   //定时器消息  10秒触发一次
       {
                     //等待事件对象beginEvent被激活
                     WaitForSingleObject(beginEvent,INFINITE);                     /////////读共享内存区,并赋值
      HANDLE hFile;
     hFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,NULL,"Share");
     DATA *dataVal=NULL;
     dataVal=(DATA *)MapViewOfFile(hFile,FILE_MAP_ALL_ACCESS,0,0,0); WORD uData[100];
for (int j=0;j<100;j++)
{
   uData[j]=dataVal->val[j];
} UnmapViewOfFile(dataVal);
CloseHandle(hFile);
                       ...
                       ...
                   }
                }
         }
  return 0;
}//线程C略第一次使用共享内存的方法,有很多地方不是很清楚,我在A和B中,创建和解除共享内存分别放在了循环里和循环外,哪种方法是正确的?还有如果线程A、B、C同时启动,那像我这样用事件对象进行同步有什么问题没有?又或者我的程序在处理思路上是否有问题?请高手不吝赐教。

解决方案 »

  1.   

    多线程要等所有的线程都不使用的时候再 UnmapViewOfFile
      

  2.   

    struct     DATA 

          WORD   val[100]; 
    }; 如果我在共享内存中数组的长度是不定长的,那么我该怎么定义结构体?可以在结构体中定义一个指针变量吗?
    struct DATA 

         int    nLen;  //数据长度
         LPWORD   val; //指针
    };
      

  3.   

    看你的代码,应该是在同一进程中的多线程吧?
    不需要用FileMapping, 就用一般的内存区就可以,注意用临界区保护就可。
      

  4.   

    可以在结构体中定义指针变量。
    另外,进程内的内存本身就是所有线程共享的,不需要FileMapping。使用时可以用同步对象来实现同步。