用户同步方法的比较

来源:互联网 发布:如何修改淘宝店铺名称 编辑:程序博客网 时间:2024/06/05 15:33

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家拍砖!

 

代码下载:http://www.rayfile.com/zh-cn/files/67e13cdc-0a41-11e2-b904-0015c55db73d/

一、编译报错

编译代码成功,运行后报以下错误:

ReleaseSRWLockShared介绍:

释放一个可读可写的锁,它在共享模式中被获得。SRWLockExclusive是内核模式下的线程同步,只支持vista及以上系统。

Minimum supported client

Windows Vista

Minimum supported server

Windows Server 2008

VOID WINAPI ReleaseSRWLockShared(  _Inout_  PSRWLOCK SRWLock);

通过报错内容分析,那是因为引用dll里的某个函数ReleaseSRWLockShared,但dll中根本不存在该函数。
通过以上知识知道了原因,ReleasLockShared要求的最低系统是Vista,而我的电脑是XP的,所以当然运行就报错了。
与ReleaseLockShared类似的API有AcquireSRWLockExclusive、ReleaseSRWLockExclusive、AcquireSRWLockShared。

二、

 

1、 

主线程中创建多个线程,个数为执行方法个数*nThreads个(意思即每个方法创建nThreads个),

而nThreads的取值有两个2和4,执行方法个数为7个,这样总共创建的线程个数为7*(2+4)=42。

创建的步骤是按方法,每个方法创建nThread个线程,等线程退出后再执行下一个方法的线程创建,依次类推。

 

在创建时把主线程的优先级设置为THREAD_PRIORITY_HIGHEST,创建线程创建完成时把优先级设置为THREAD_PRIORITY_NORMAL。

如下图:

 

函数为:

void MeasureConcurrentOperation(   TCHAR* operationName, DWORD nThreads, OPERATIONFUNC operationFunc) {   HANDLE* phThreads = new HANDLE[nThreads];   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);   for (DWORD currentThread = 0; currentThread < nThreads; currentThread++) {      phThreads[currentThread] =          CreateThread(NULL, 0, ThreadIterationFunction, operationFunc, 0, NULL);   }   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);   CStopwatch watch;   WaitForMultipleObjects(nThreads, phThreads, TRUE, INFINITE);   __int64 elapsedTime = watch.Now();   _tprintf(   TEXT("Threads=%u, Milliseconds=%u, Test=%s\n"),       nThreads, (DWORD)elapsedTime, operationName);   // Don't forget to clean up the thread handles   for (DWORD currentThread = 0; currentThread < nThreads; currentThread++) {      CloseHandle(phThreads[currentThread]);   }   delete phThreads;}


七种方法:

(1)无线程同步,属于不稳定的读。因为只是读所以不会发生资源竞争

void WINAPI VolatileReadCallback(){   LONG lValue = gv_value; }


 

(2)无线程同步,属于不稳定的写。可能发生资源竞争

void WINAPI VolatileWriteCallback(){   gv_value = 0; }


(3)采用原子操作的自增。

void WINAPI InterlockedIncrementCallback(){InterlockedIncrement(&gv_value);}

(4)采用关键代码段进行同步

CRITICAL_SECTION  g_cs;void WINAPI CriticalSectionCallback(){EnterCriticalSection(&g_cs);gv_value = 0;LeaveCriticalSection(&g_cs);}

(5)采用互斥体进行同步

HANDLE g_hMutex;void WINAPI MutexCallback(){WaitForSingleObject(g_hMutex, INFINITE);gv_value = 0;ReleaseMutex(g_hMutex);}

(6)可读可写的共享锁(Vista中才可使用)

SRWLOCK g_srwLock;InitializeSRWLock(&g_srwLock);void WINAPI SRWLockReadCallback() {AcquireSRWLockShared(&g_srwLock);gv_value = 0;ReleaseSRWLockShared(&g_srwLock);}


(7)可读可写的执行锁(Vista中才可使用)

void WINAPI SRWLockWriteCallback() {AcquireSRWLockExclusive(&g_srwLock);gv_value = 0;ReleaseSRWLockExclusive(&g_srwLock);}


结论:在安全的同步方式中原子操作的 InterlockedIncrement的效率最高,然后依次是关键代码段,最后是互斥锁

 

三、总结:

1自动算运算时间的类CStopwatch

// Stop watch class from Chapter 7class CStopwatch {public:   CStopwatch() { QueryPerformanceFrequency(&m_liPerfFreq); Start(); }   void Start() { QueryPerformanceCounter(&m_liPerfStart); }   // Returns # of milliseconds since Start was called   __int64 Now() const {         LARGE_INTEGER liPerfNow;      QueryPerformanceCounter(&liPerfNow);      return(((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000)          / m_liPerfFreq.QuadPart);      }private:   LARGE_INTEGER m_liPerfFreq;   // Counts per second   LARGE_INTEGER m_liPerfStart;  // Starting count};


 

 

原创粉丝点击