类似信号量互斥的问题,有没有现成的只读锁可以用?

w_anthony 2007-10-09 04:05:58
现在需要设置多线程互斥访问一部分数据,但是大部分线程都是读操作,所以这些线程可以同时访问这些数据,另外又存在一些写操作的线程,不仅这些线程之间需要互斥,而且也需要与读操作的线程进行互斥。
有没有现成的类或者API可以直接拿来用的呢?
...全文
147 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
w_anthony 2007-12-28
  • 打赏
  • 举报
回复
To LS, 我开了100个线程做那个循环,1~2分钟后终止循环(通过一个标记),没有出现死锁的情况。
而且我分析了下CSWMRG的代码,也没有发现什么问题。
或许你的死锁是别的原因引起的,1000的对象共享100个线程,这里也是有一个互斥量的,看看会不会是这个的问题?
又或者是你是TerminateThread结束线程,那就更加有可能出现死锁了……
织梦科技 2007-12-28
  • 打赏
  • 举报
回复
CSWMRG类 有bug 偶尔会出现死锁。
------------------------------

我是这样测试的:


对话框中的成员变量 CSWMRG m_cs;,只被类CXTaskRead访问。

void CXTaskRead::Run()
{
m_pDlg->m_cs.WaitToRead();
::Sleep(500);
m_pDlg->m_cs.Done();
}
看上面的代码,实际上这里根本不需要加锁,我只想测试一下CSWMRG是否能正常工作。

启动线程池时,往线程池中同时加入1000个CXTaskRead对象和100个线程。
我会在任务执行过程中强迫停止线程池,有时任务线程会死锁。

经调试,任务管理线程已经退出

如果用CCriticalSection 不会出现死锁
w_anthony 2007-10-09
  • 打赏
  • 举报
回复
yxz_lp,多谢!!!
yxz_lp 2007-10-09
  • 打赏
  • 举报
回复
更正:
应该是CSWMRG类:

/******************************************************************************
Module: SWMRG.h
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/


#pragma once


///////////////////////////////////////////////////////////////////////////////


class CSWMRG {
public:
CSWMRG(); // Constructor
~CSWMRG(); // Destructor

VOID WaitToRead(); // Call this to gain shared read access
VOID WaitToWrite(); // Call this to gain exclusive write access
VOID Done(); // Call this when done accessing the resource

private:
CRITICAL_SECTION m_cs; // Permits exclusive access to other members
HANDLE m_hsemReaders; // Readers wait on this if a writer has access
HANDLE m_hsemWriters; // Writers wait on this if a reader has access
int m_nWaitingReaders; // Number of readers waiting for access
int m_nWaitingWriters; // Number of writers waiting for access
int m_nActive; // Number of threads currently with access
// (0=no threads, >0=# of readers, -1=1 writer)
};


//////////////////////////////// End of File //////////////////////////////////
/******************************************************************************
Module: SWMRG.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/


#include "..\CmnHdr.h" /* See Appendix A. */
#include "SWMRG.h"


///////////////////////////////////////////////////////////////////////////////


CSWMRG::CSWMRG() {

// Initially no readers want access, no writers want access, and
// no threads are accessing the resource
m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
m_hsemReaders = CreateSemaphore(NULL, 0, MAXLONG, NULL);
m_hsemWriters = CreateSemaphore(NULL, 0, MAXLONG, NULL);
InitializeCriticalSection(&m_cs);
}


///////////////////////////////////////////////////////////////////////////////


CSWMRG::~CSWMRG() {

#ifdef _DEBUG
// A SWMRG shouldn't be destroyed if any threads are using the resource
if (m_nActive != 0)
DebugBreak();
#endif

m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
DeleteCriticalSection(&m_cs);
CloseHandle(m_hsemReaders);
CloseHandle(m_hsemWriters);
}


///////////////////////////////////////////////////////////////////////////////


VOID CSWMRG::WaitToRead() {

// Ensure exclusive access to the member variables
EnterCriticalSection(&m_cs);

// Are there writers waiting or is a writer writing?
BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));

if (fResourceWritePending) {

// This reader must wait, increment the count of waiting readers
m_nWaitingReaders++;
} else {

// This reader can read, increment the count of active readers
m_nActive++;
}

// Allow other threads to attempt reading/writing
LeaveCriticalSection(&m_cs);

if (fResourceWritePending) {

// This thread must wait
WaitForSingleObject(m_hsemReaders, INFINITE);
}
}


///////////////////////////////////////////////////////////////////////////////


VOID CSWMRG::WaitToWrite() {

// Ensure exclusive access to the member variables
EnterCriticalSection(&m_cs);

// Are there any threads accessing the resource?
BOOL fResourceOwned = (m_nActive != 0);

if (fResourceOwned) {

// This writer must wait, increment the count of waiting writers
m_nWaitingWriters++;
} else {

// This writer can write, decrement the count of active writers
m_nActive = -1;
}

// Allow other threads to attempt reading/writing
LeaveCriticalSection(&m_cs);

if (fResourceOwned) {

// This thread must wait
WaitForSingleObject(m_hsemWriters, INFINITE);
}
}


///////////////////////////////////////////////////////////////////////////////


VOID CSWMRG::Done() {

// Ensure exclusive access to the member variables
EnterCriticalSection(&m_cs);

if (m_nActive > 0) {

// Readers have control so a reader must be done
m_nActive--;
} else {

// Writers have control so a writer must be done
m_nActive++;
}

HANDLE hsem = NULL; // Assume no threads are waiting
LONG lCount = 1; // Assume only 1 waiter wakes; always true for writers

if (m_nActive == 0) {

// No thread has access, who should wake up?
// NOTE: It is possible that readers could never get access
// if there are always writers wanting to write

if (m_nWaitingWriters > 0) {

// Writers are waiting and they take priority over readers
m_nActive = -1; // A writer will get access
m_nWaitingWriters--; // One less writer will be waiting
hsem = m_hsemWriters; // Writers wait on this semaphore
// NOTE: The semaphore will release only 1 writer thread

} else if (m_nWaitingReaders > 0) {

// Readers are waiting and no writers are waiting
m_nActive = m_nWaitingReaders; // All readers will get access
m_nWaitingReaders = 0; // No readers will be waiting
hsem = m_hsemReaders; // Readers wait on this semaphore
lCount = m_nActive; // Semaphore releases all readers
} else {

// There are no threads waiting at all; no semaphore gets released
}
}

// Allow other threads to attempt reading/writing
LeaveCriticalSection(&m_cs);

if (hsem != NULL) {

// Some threads are to be released
ReleaseSemaphore(hsem, lCount, NULL);
}
}


//////////////////////////////// End of File //////////////////////////////////


yxz_lp 2007-10-09
  • 打赏
  • 举报
回复
现成的类,有啊。
《Windows 核心编程》(第十章 线程同步工具包) 里的COptex类
zaodt 2007-10-09
  • 打赏
  • 举报
回复

CreateEvent() API 函数

用法网上搜。
美丽海洋 2007-10-09
  • 打赏
  • 举报
回复
CS

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧