一个dll,大致结构如下:
一全局变量:g_ggg;
一个套节字重叠IO使用的回调函数(完成例程);
一个线程;
若干个导出方法。
uint g_ggg;
void CALLBACK CompletionROUTINE(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
{
//使用g_ggg,包括读写
...
}unsigned int __stdcall WorkThread(void* pVoid)
{
//使用g_ggg,包括读写
WSASend(..., CompletionROUTINE);
}dllexport void fun1()
{
//使用g_ggg,包括读写
}dllexport void fun2()
{
//使用g_ggg,包括读写
}
语法不一定正确,大家明白意思即可。现在我的问题是,有什么办法对g_ggg互斥最好,要求速度第一,麻烦一点都不在乎。
另外提一点,对g_ggg访问的地方很多,不止上面提到的那几处。

解决方案 »

  1.   

    能不能尝试自己写个读写类呢?
    // CDataClass.h 头文件#include "afxmt.h"class CDataClass
    {
    public:
        CDataClass();
        ~CDataClass();    void SetData(xxxx);    UINT operator=() const;private:
        UINT g_ggg;
        CMutex m_hMutex;
    };
    在类中的 SetData 成员函数中,使用 CMutex 类
    // CDataClass.h 代码void CDataClass::SetData(xxxx)
    {
        m_hMutex.Lock();
        // 这里进行数据写操作
        m_hMutex.Unlock();
    }UINT CDataClass::operator=() const
    {
        return g_ggg;
    }大致这样吧,等其他高人补充~
      

  2.   

    昏,重载操作符那里可能有误,你自己修改调试一下~把你的全局变量 uint g_ggg 该为 CDataClass xxx
    然后直接对类进行操作~
    我想这样是最方便的了~至于速度嘛,因为要同步,所以……
      

  3.   

    fun1,fun2,workthread,CompletionROUTINE 可以并行运行。设计一个信号量,并有读操作的引用计数, 没进入读操作,对引用计数+1,完成读操作引用计数-1。设计一个Event,写操作发生时event为无信号,写操作完成时event为有信号。读操作不去更改event的信号状态读操作和写操作进入前都在等待event,另外写操作在等待event的同时还要等待信号量的引用计数为0(即没有读操作)才能进入。
    按以上做法,逻辑上还存在一个问题:有读操作正在进行,写操作正在等待信号量的引用计数为0,这时又有新的读操作发生,这个的读操作就又进入了,极限情况,不断有读操作发生,信号量的引用计数一直就不能为0,导致写操作一直等待。也就是在这种情况下,读操作优先权更大了,不平等竞争。
    LZ考虑一下这种情况现实是否会发生,如果会,那就需要再次基础上再增加逻辑。再增加的逻辑,
    再设计一个Event2,初始有信号,写操作进入等待Event和信号量前,先把Event2设为无信号,等待成功后马上将Event2设为有信号。读操作不设置Event2的信号状态,只是等待event之前先等待Event2。
      

  4.   

    for efficency, CriticalSection is your choice
      

  5.   

    可不可以像what_a_big 说的那样,在任何访问g_ggg的地方加上:EnterCriticalSection(&crs);
    g_ggg++;
    LeaveCriticalSection(&crs);这样速度如何?
      

  6.   

    上面的g_ggg++; 
    只是示例,我对g_ggg的修改不光是++和--,主要是位运算。
      

  7.   

    直接用临界区或是 互斥量 对所有的 g_ggg进行同步,那效率是比较低的,相当于涉及到g_ggg操作时全都顺序执行了,同一时间只能一个进行访问。效率要高,就是要使得 读的时候可以并发。
      

  8.   


    那么读的时候就直接读。写的时候用 _InterlockedExchange( &g_ggg, newValue );
    PS: #include <intrin.h>_InterlockedExchanger的底层实现是对xchg指令加上lock前缀,执行的时候会锁住总线,只能有一个CPU访问内存,且为原子指令,效率极高……
      

  9.   

    不是那么简单啊,大多数情况是,先读g_ggg,然后根据其内容来决定是否要写g_ggg,以及写什么值,这个过程是不能被其它线程中断的!
      

  10.   


    这样就不能并发读了。
    因为如果有两个线程同时读,并且一个线程把g_ggg加1并写回,另一个线程也是如此,那么g_ggg最终只加了1而不是2。
    楼主对于什么时候能并发读,再考虑一下吧。要实现你说的“根据其内容来决定是否要写g_ggg”,就不能并发读,而要用临界区或互斥量。
    EnterCriticalSection( cs );
    if( CanWrite( g_ggg ) )
      {
      g_ggg = xxx;
      }
    LeaveCriticalSection( cs );
    这是唯一正确的办法。