社区
进程/线程/DLL
帖子详情
一个比较经典的同步问题:一个写/多个读
Necromancerr
2004-10-20 05:39:58
一个比较经典的同步问题:一个写/多个读,规则如下:
1.一个人在写时,其他人不允许写。
2.一个人在写时,其他人不允许读。
3.一个人在读时,其他人不允许写。
4.一个人在读时,其他人允许读。
允许使用Mutex、Event、Semaphore、CriticalSection等任意对象,求实现代码。
求实现代码。
...全文
535
27
打赏
收藏
一个比较经典的同步问题:一个写/多个读
一个比较经典的同步问题:一个写/多个读,规则如下: 1.一个人在写时,其他人不允许写。 2.一个人在写时,其他人不允许读。 3.一个人在读时,其他人不允许写。 4.一个人在读时,其他人允许读。 允许使用Mutex、Event、Semaphore、CriticalSection等任意对象,求实现代码。 求实现代码。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
27 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
guodong_77
2004-11-09
打赏
举报
回复
晕,都要代码啊,我有书,要不要撒都,^_^。
zhiguo_he
2004-11-09
打赏
举报
回复
我也要一份,谢谢先 zhiguo_he@163.com
zzxenjoy
2004-11-08
打赏
举报
回复
ding
allenq
2004-11-06
打赏
举报
回复
谢谢,我要一份, allenq@163.com
72193
2004-11-06
打赏
举报
回复
我也要 0459@sohu.com
linxy2002
2004-11-06
打赏
举报
回复
DentistryDoctor(雅克医生<医德,值得反思>)
也给我一份吧,我的 linxy_2002@yahoo.com.cn
ChinaOk
2004-11-06
打赏
举报
回复
第一类: 写者优先
条件:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
解2:如果读者数不固定,采用下面的算法:
设置三个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据
rmutex 用于读者互斥的访问读者计数器readcount
nrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作
var rwmutex, rmutex,nrmutex : semaphore := 1,1,1 ;
int readcount = 0;
cobegin
readeri begin // i=1,2,….
P(rwmutex);
P(rmutex);
Readcount++;
If (readcount == 1) P(nrmutex); //有读者进入,互斥写操作
V(rmutex);
V(rwmutex); // 及时释放读写互斥信号量,允许其它读、写进程申请资源
读数据;
P(rmutex);
Readcount--;
If (readcount == 0) V(nrmutex); //所有读者退出,允许写更新
V(rmutex);
End
Writerj begin // j = 1,2,….
P(rwmutex); // 互斥后续其它读者、写者
P(nrmutex); //如有读者正在读,等待所有读者读完
写更新;
V(nrmutex); //允许后续新的第一个读者进入后互斥写操作
V(rwmutex); //允许后续新读者及其它写者
End
Coend
ChinaOk
2004-11-06
打赏
举报
回复
写者优先
posedge
2004-11-05
打赏
举报
回复
核心编程
这本书里面很多的
lianglp
2004-11-04
打赏
举报
回复
void LeaveCriticalSectionState()//这个应写为:
{
::EnterCriticalSection(&csSetupCounterSection) ;
nReadCounter-- ;
if(nReadCounter == 0)
{
::LeaveCriticalSection(&sWriteSection) ;//如果为最后一个退出读状态,则关闭与写临界区的互拆
}
::LeaveCriticalSection(&csSetupCounterSection) ;
}
lianglp
2004-11-04
打赏
举报
回复
//假设临界区变量已初始化好。
int nReadCounter = 0 ;
CRITICAL_SECTION csWriteSection ;
CRITICAL_SECTION csSetupCounterSection ;
void EnterCriticalSectionState()
{
::EnterCriticalSection(&csSetupCounterSection) ;
if(nReadCounter == 0)
{
::EnterCriticalSection(&sWriteSection) ;//如果第一次读,则进入与写互拆的临界区
}
nReadCounter++ ;
::LeaveCriticalSection(&csSetupCounterSection) ;
}
void LeaveCriticalSectionState()
{
::EnterCriticalSection(&csSetupCounterSection) ;
nReadCounter-- ;
if(nReadCounter == 0)
{
::EnterCriticalSection(&sWriteSection) ;//如果为最后一个退出读状态,则关闭与写临界区的互拆
}
::LeaveCriticalSection(&csSetupCounterSection) ;
}
/////////////////////////////////////////////////
//以下一个为读线程,一个为写线程
DWORD __stdcall ReadThread(LPVOID pContext)//读线程
{
EnterCriticalSectionState() ;
//自己想做读的事情
...
ReadFunction() ;...
LeaveCriticalSectionState() ;
return NULL ;
}
DWORD __stdcall WriteThread(LPVOID pContext)//写线程
{
::EnterCriticalSection(&sWriteSection) ;
//自己想做写的事情
...
WriteFunction() ;
::LeaveCriticalSection(&sWriteSection) ;
return NULL ;
}
linxy2002
2004-11-04
打赏
举报
回复
帮忙顶,顺便接分
beyondtkl
2004-11-04
打赏
举报
回复
是哦 核心编程 里面有详细的说明 & 例子。。
里面代码 偶也有。。谁要的 发信息给我。。
xyg1985109
2004-11-04
打赏
举报
回复
DentistryDoctor(雅克医生<医德,值得反思>) :
能给我一份源程序嘛,我最近正在学习操作系统,刚好学完了线程,正准备看《windows核心编程》,能给我你的源代码让我学习一下嘛?因为我不知道我该怎么写那个框架!
也要向楼上的学习学习啊。。我现在还不是很熟悉api函数,有时候想要实现一些功能,得要差半天书!唉,学习中啊。。
icelight
2004-10-22
打赏
举报
回复
回楼上: 你的问题可用信号灯Semaphore解决。
DWORD threadA(void* pD)
{
int iID=(int)pD;
//在内部重新打开
HANDLE hCounterIn=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"sam sp 44");
for(int i=0;i<3;i++)
{
printf("%d wait for object\n",iID);
WaitForSingleObject(hCounterIn,INFINITE);
printf("\t\tthread %d : do database access call\n",iID);
Sleep(100);
printf("\t\tthread %d : do database access call end\n",iID);
ReleaseSemaphore(hCounterIn,1,NULL);
}
CloseHandle(hCounterIn);
return 0;
}
//in main function
{
//创建信号灯
HANDLE hCounter=NULL;
if( (hCounter=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"sam sp 44"))==NULL)
{
//如果没有其他进程创建这个信号灯,则重新创建
hCounter = CreateSemaphore(NULL,2,2,"sam sp 44");
}
//创建线程
HANDLE hThread[3];
CWinThread* pT1=AfxBeginThread((AFX_THREADPROC)threadA,(void*)1);
CWinThread* pT2=AfxBeginThread((AFX_THREADPROC)threadA,(void*)2);
CWinThread* pT3=AfxBeginThread((AFX_THREADPROC)threadA,(void*)3);
hThread[0]=pT1->m_hThread;
hThread[1]=pT2->m_hThread;
hThread[2]=pT3->m_hThread;
//等待线程结束
WaitForMultipleObjects(3,hThread,TRUE,INFINITE);
//关闭句柄
CloseHandle(hCounter);
}
xujungood
2004-10-21
打赏
举报
回复
我在windows下面写过一个程序,一个消费者,多个生产者,双方都判断变量bGoon,如果bGoon是false则跳出循环,否则循环。
但是只有把消费者线程和生产者线程都在循环中设置了一定延时才能安全推出,否则,当退出程序,关闭线程的时候,程序会死掉,
这是怎么回事啊?~
哪位高手能告诉我一下
flybusflybus
2004-10-21
打赏
举报
回复
实现代码
#include <Thread.h>
SNMPRWLock::SNMPRWLock()
{
};
bool SNMPRWLock::init(bool flag)
{
#if defined(WIN32)
hRWMutex = CreateEvent(NULL,FALSE,TRUE,NULL);
hReaderEve = CreateEvent(NULL,TRUE,FALSE,NULL);
bWriterFirst = flag;
iRefWriter = -1;
iRefReader = -1;
if(bWriterFirst)
{
hWriterEve = CreateEvent(NULL,TRUE,TRUE,NULL);
}
#else
pthread_rwlockattr_init(&attr);
pthread_rwlock_init(rw_lock, &attr)
#endif
return true;
};
void SNMPRWLock::fini()
{
#if defined(WIN32)
CloseHandle(hReaderEve);
CloseHandle(hRWMutex);
if(bWriterFirst)
{
CloseHandle(hWriterEve);
}
#else
pthread_rwlockattr_destroy(&attr);
pthread_rwlock_destroy(rw_lock);
#endif
};
void SNMPRWLock::acquire_read()
{
#if defined(WIN32)
if(bWriterFirst)
{
WaitForSingleObject(hWriterEve,INFINITE);
}
if(0 == InterlockedIncrement(&iRefReader))
{
WaitForSingleObject(hRWMutex, INFINITE);
SetEvent(hReaderEve);
};
WaitForSingleObject(hReaderEve,INFINITE);
#else
pthread_rwlock_rdlock(rw_lock);
#endif
};
void SNMPRWLock::acquire_write()
{
#if defined(WIN32)
if(bWriterFirst)
{
if(0 == InterlockedIncrement(&iRefWriter))
{
ResetEvent(hWriterEve);
}
}
WaitForSingleObject(hRWMutex, INFINITE);
#else
pthread_rwlock_wrlock(rw_lock);
#endif
};
void SNMPRWLock::Release()
{
#if defined(WIN32)
if(WAIT_TIMEOUT == WaitForSingleObject(hReaderEve,0))
{
SetEvent(hRWMutex);
if(bWriterFirst)
{
if(InterlockedDecrement(&iRefWriter) < 0 )
{
SetEvent(hWriterEve);
}
}
}
else if(InterlockedDecrement(&iRefReader) < 0)
{
ResetEvent(hReaderEve);
SetEvent(hRWMutex);
};
#else
pthread_rwlock_unlock(rw_lock);
#endif
};
flybusflybus
2004-10-21
打赏
举报
回复
我前几天正好写了一个,windows和solaris下都简单测试了,没有问题,也没有时间看,正好贴出来大家用,大家嗖嗖的目光帮我把把关(另外写锁优先的实现,windows下和solaris提供的天然写锁其实效果不尽相同,solaris下是通过提高线程优先级,而我的代码是通过代码逻辑,大家可以按需取舍)
#ifndef MYGOD
#define MYGOD
#if defined(WIN32)
#if _MSC_VER > 1000
#pragma once
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <pthread.h>
#endif
class SNMPRWLock
{
public:
SNMPRWLock(); //构造函数
private:
#if defined(WIN32)
HANDLE hRWMutex; //读写、写写互斥锁
HANDLE hReaderEve; //读事件
HANDLE hWriterEve; //写事件
long iRefReader; //读者引用记数
long iRefWriter; //写者引用记数
bool bWriterFirst; //通过写锁优先开关,避免提前优化带来的负面影
#else
pthread_rwlockattr_t attr; //读写锁属性对象
pthread_rwlock_t rw_lock; //读写锁
#endif
public:
bool init(bool); //初始化函数,参数表示是否需要写锁优先
void fini(); //回收函数
void acquire_read(); //加读锁
void acquire_write(); //加写锁
void Release(); //放锁
};
#endif
zdleek
2004-10-21
打赏
举报
回复
《Windows核心编程》经典著作
alexmayer
2004-10-21
打赏
举报
回复
搬个凳子坐下听讲!
顺便帮顶混分!
加载更多回复(7)
转载130个原文网站,原文链接:https://blog.csdn.net/qq_43901693/article/details/100606828
文章目录130 余个相见恨晚的超实用网站搞学习找书籍冷知识 / 黑科技
写
代码资源搜索小工具导航页(工具集)看视频学设计搞文档找图片 搞学习 CSDN: https://www.csdn.net/ TED(最优质的演讲):...
同步
FIFO 两种方法
一、当
写
指针超过
读
指针一圈,
写
满;
写
指针等于
读
指针,
读
空 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // ...
经典
调度
问题
:
读
者优先/
写
者优先算法
文章目录算法介绍
读
者优先:
写
者优先:多线程编程注意事项
写
者优先算法流程图 算法介绍 创建
一个
包含n 个线程的控制台进程。用这n 个线程来表示n个
读
者或
写
者。...
写
者优先:如果
一个
读
者申请进行
读
操作时已有...
操作系统:
经典
进程
同步
问题
之 生产者-消费者
问题
、
读
者-
写
者
问题
、哲学家进餐
问题
在进程
同步
中,
经典
的
同步
问题
有:生产者-消费者
问题
、
读
者-
写
者
问题
、哲学家进餐
问题
。 一、生产者与消费者
问题
:
问题
描述:使用
一个
缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品;只有缓冲区不为...
经典
的进程
同步
问题
-----
读
者-
写
者
问题
详解
经典
的进程
同步
问题
-----
读
者-
写
者
问题
详解 ... 进程
同步
问题
是
一个
非常重要且相当有趣的
问题
,本文我们对其中
比较
有名的
读
者-
写
者
问题
来进行探讨。
读
者-
写
者
问题
是指保证
一个
Writer进程必须与其他...
进程/线程/DLL
15,471
社区成员
49,182
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章