创建了一个复合文件,现在想使用多个线程对该复合文件下多个IStream对象所指数据区进行操作,但是如何保证针对同一IStream数据区只有一条线程在操作?尝试用了IStream对象中的IStream::LockRegion和IStream::UnlockRegion也无法满足要求。

解决方案 »

  1.   

    没想到还有人研究这个系统会保证的,因为ZwMapViewOfSection可以返回STATUS_CONFLICTING_ADDRESSES
      

  2.   

    不需要自己来管理吗?系统如何保证?就是数据库还需要锁定一下资源吧,何况是一个文件内的部分数据呢。
    如果我自己来锁定IStream资源,如何操作?
      

  3.   

    什么IStorage/IStream,不就是memory-mapped file么你以为内部有什么神秘的,不过是直接调用的ZwMapViewOfSection
      

  4.   

    tcige 兄台,能讲详细点不?
    如果我创建的两个线程同时对IStream所指定的同一块数据进行操作的话,如何确保数据的准确性,不也要等写完了再由其他线程读取吗?是这样的,我做一个小程序,想用复合文件存储一些临时数据,这些临时数据是每隔一段时间要做一次更新的,其余时间都是其他线程进行访问,只读不写的。如何在我第一个线程进行写的时候其他线程等候,也就是想把我线程1正在写的这块数据把它Lock起来,类似于CriticalSection 把独占,在线程使用完了我再释放,让其他线程使用。
      

  5.   

    没源代码,不知道IStream具体是怎么做的,差不多就行了,反正我是不会自己再加锁的不管多少个IStream,总共就一份map,前面的会unmap,不存在map之间的同步另外别的不说,IStream是一个组件的接口,不知道具体的ThreadingModel不过不可能是mta,因为没产生线程池,所以IStream::Read/Write显然是同步的而且你QueryInterface一下,会发现是有IMarshal接口的,所以多线程内部肯定考虑的
      

  6.   

    采用DWORD dwMode=STGM_READWRITE | STGM_SHARE_EXCLUSIVE; 创建文件,创建IStorage都是能成功的,按MSDN上面所说的,如果我创建STGM_TRANSACTED方式的,采用
    dwMode=STGM_TRANSACTED | 0x00400000L | STGM_READWRITE | STGM_SHARE_DENY_WRITE;
    创建文件是成功的,但是创建IStorage就会失败,为什么?(在这里0x00400000L 是STGM_DIRECT_SWMR)
      

  7.   

    USES_CONVERSION;
    DWORD dwMode=NULL;
    // dwMode=STGM_READWRITE | STGM_SHARE_EXCLUSIVE; // (1)第1种方式
    dwMode=STGM_TRANSACTED | 0x00400000L | STGM_READWRITE | STGM_SHARE_DENY_WRITE;// (2)第2种方式
    CString sFile=_T("C:\\test.stg"), sStgSec=_T("TEST_STG");
    IStorage* pStorageFile=NULL;
    IStorage* pStg=NULL;hr = ::StgCreateDocfile(T2COLE(sFile), dwMode|STGM_CREATE,
    0, &pStorageFile); // (1),(2)都成功
    pStorageFile->CreateStorage(T2COLE((LPCTSTR)sStgSec),
    dwMode|STGM_CREATE,
    0,0,&pStg); // (1)成功,(2)失败
    ASSERT(pStg);不解!!!!
    知道的说一下,到底是那个地方出错了。
    我想实现一个线程可以写,其他线程为只读。
      

  8.   


    信他你就死了。
    IStream是个COM接口,跟映射文件有什么关系?即使某个对象是用映射文件来实现的,不保证所有对象都是这样,或者某个IStream对象是用来操作网络呢。
      

  9.   

    为什么用“dwMode=STGM_TRANSACTED | 0x00400000L | STGM_READWRITE | STGM_SHARE_DENY_WRITE;// (2)第2种方式”
    就会失败呢?