扩展阅读
  • Windows下php 5.3.5和apache2安装配置及测试
  • 大家推荐一个windows下的java开发平台。工具本身是为windows优化的。jbuilder太慢。
  • ​Windows Server 2016提供Docker原生运行的企业级支持
  • windows下写的代码 gb2312 如何转成 LINUX和WINDOWS都可正常显示的代码
  • windows堆栈溢出利用的七种方式
  • 用linux(服)windows(客)传输文件,windows端可以,linux端不可以,怎么回事???
  • windows 7下打开或者关闭telnet客户端/服务端命令方法操作步骤
  • linux环境下安装windows打印机问题。。没有驱动,能否在无界面的linux上安装windows虚拟机??
  • Windows 8.1中文英文预览版系统下载及功能改进
  • windows下用wincvs弄下来的emacs源码全是windows格式的,晕!!!
  • tar.xz如何解压:linux和windows下tar.xz解压命令介绍
  • docker中文入门学习手册 iis7站长之家
  • MTU介绍以及在windows和linux下怎么设置MTU值
  • 如何修改启动菜单的启动顺序(linux,windows),我想让系统默认启动到windows.谢谢!!
  • windows7操作系统介绍及各种使用技巧总结
  • 急需windows server 2003系统c:windowssystem32文件夹下winlogon.exe、licdll.dll两个文件,在线等待!
  • Windows下Docker应用部署相关问题详解
  • 多操作系统(windows98windows2000linux)怎么按装最合适???
  • Windows 7 32位下 MongoDB安装步骤
  • asp只能在windows上运行吗,jsp可以在windows也可以在unix上运行吗
  • windows下cmd命令提示符下让程序后台运行命令
  • 红旗Linux在局域网上能访问Windows的网上邻居上的windows98机器中的文件系统吗?
  •  
    当前位置:  编程语言>c/c++

    最新Windows下c++读写锁SRWLock介绍

     
        发布时间:2013-10-17  


        本文导语:  读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。对于读取者线程,读写锁会允许他们并发的执行。当有写入者线程在占有资源时,读写锁会让...

       读写在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。对于读取者线程,读写锁会允许他并发的执行。当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。因此用读写锁来解决读者写者问题会使代码非常清晰和简洁。

    SRWLock

     从visual studio2005开始你可以使用SRWLock,和CRITICAL_SECTION(关键段)差不过的功能,不同的是由程序员控制读写线程,如果是读线程,可以同时读取,如果是写线程,则其他线程挂起,写完后马上就可以读取

    首先,需要一个SRWLOCK结构,然后调用InitializeSRWLock(PSWRLOCK srwLock)函数初始化这个结构.

    SRWLOCK srw;
    InitializeSRWLock(&srw);
    一旦初始化完成,就可以对写入线程调用AcquireSRWLockExclusive()函数和ReleaseSRWLockExclusive()函数
    AcquireSRWLockExclusive(&srw);
    //...写入数据,写入东西的时候该线程独占,其他任何线程不可进入
    ReleaseSRWLockExclusive(&srw);
    对于只读线程可以调用AcquireSRWLockShared()函数和ReleaseSRWLockShared()函数,如下
     AcquireSRWLockShared(&srw);
    //..读取数据,如果这时没有写入数据则多个读取线程可以进行
     ReleaseSRWLockShared)&srw);


    Slim读/写锁

       SRWLock的目的和关键段相同:对一个资源进行保护,不让其它线程访问它。但是,与关键段不同的是,SRWLock允许我们区分哪些想要读取资源的值的线程(读取者线程)和想要更新资源的值的线程(写入者线程)。让所有的读取者线程在同一时刻访问共享资源应该是可行的,这是因为仅仅读取资源的值并不存在破坏数据的风险。只有当写入者线程想要对资源进行更新的时候才需要进行同步。在这种情况下,写入者线程想要对资源进行更新的时候才需要进行同步。在这种情况下,写入者线程应该独占对资源的访问权:任何其它线程,无论是读取者线程还是写入者线程,都不允许访问资源。这就是SRWLock提供的全部功能。

       首先,我们需要分配一个SRWLOCK结构并用InitializeSRWLock函数对它进行初始化:

       VOID InitializeSRWLock(PSRWLOCK SRWLock);

       一旦SRWLock初始化完成之后,写入者线程就可以调用AcquireSRWLockExclusive,将SRWLOCK对象地址作为参数传入,以尝试获得对被保护资源的独占访问权。

       VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock);

     完成对资源的更新之后,应该调用ReleaseSRWLockExclusice,并将SRWLOCK对象的地址作为参数传入,这样就解除了对资源的锁定。

       VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock);

    对读取者线程来说,同样有两个步骤,单调用的是下面两个新的函数:

       VOID AcquireSRWLockShared(PSRWLOCK SRWLock);

       VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);

    不存在用来删除或销毁SRWLOCK的函数,系统会自动执行清理工作

       与关键段相比,SRWLock缺乏下面两个特性

    1)不存在TryEnter(Shared/Exclusive)SRWLock 之类的函数:如果锁已经被占用,那么调用AcquireSRWLock(Shared/Exclusive) 会阻塞调用线程。

    2)不能递归地调用SRWLOCK。也就是说,一个线程不能为了多次写入资源而多次锁定资源,然后再多次调用ReleaseSRWLock* 来释放对资源的锁定。

       总结,如果希望在应用程序中得到最佳性能,那么首先应该尝试不要共享数据,然后依次使用volatile读取,volatile写入,Interlocked API,SRWLock以及关键段。当且仅当所有这些都不能满足要求的时候,再使用内核对象。因为每次等待和释放内核对象都需要在用户模式和内核模式之间切换,这种切换的CPU开销非常大。


    具体参考代码:

    //读者与写者问题继 读写锁SRWLock
    #include <stdio.h>
    #include <process.h>
    #include <windows.h>
    //设置控制台输出颜色
    BOOL SetConsoleColor(WORD wAttributes)
    {
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hConsole == INVALID_HANDLE_VALUE)
    return FALSE;
    return SetConsoleTextAttribute(hConsole, wAttributes);
    }
    const int READER_NUM = 5;  //读者个数
    //关键段和事件
    CRITICAL_SECTION g_cs;
    SRWLOCK          g_srwLock;
    //读者线程输出函数(变参函数的实现)
    void ReaderPrintf(char *pszFormat, ...)
    {
    va_list   pArgList;
    va_start(pArgList, pszFormat);
    EnterCriticalSection(&g_cs);
    vfprintf(stdout, pszFormat, pArgList);
    LeaveCriticalSection(&g_cs);
    va_end(pArgList);
    }
    //读者线程函数
    unsigned int __stdcall ReaderThreadFun(PVOID pM)
    {
    ReaderPrintf("     编号为%d的读者进入等待中...n", GetCurrentThreadId());
    //读者申请读取文件
    AcquireSRWLockShared(&g_srwLock);
    //读取文件
    ReaderPrintf("编号为%d的读者开始读取文件...n", GetCurrentThreadId());
    Sleep(rand() % 100);
    ReaderPrintf(" 编号为%d的读者结束读取文件n", GetCurrentThreadId());
    //读者结束读取文件
    ReleaseSRWLockShared(&g_srwLock);
    return 0;
    }
    //写者线程输出函数
    void WriterPrintf(char *pszStr)
    {
    EnterCriticalSection(&g_cs);
    SetConsoleColor(FOREGROUND_GREEN);
    printf("     %sn", pszStr);
    SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    LeaveCriticalSection(&g_cs);
    }
    //写者线程函数
    unsigned int __stdcall WriterThreadFun(PVOID pM)
    {
    WriterPrintf("写者线程进入等待中...");
    //写者申请写文件
    AcquireSRWLockExclusive(&g_srwLock);
    //写文件
    WriterPrintf("  写者开始写文件.....");
    Sleep(rand() % 100);
    WriterPrintf("  写者结束写文件");
    //标记写者结束写文件
    ReleaseSRWLockExclusive(&g_srwLock);
    return 0;
    }
    int main()
    {
    printf("  读者写者问题继 读写锁SRWLockn");
    printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --nn");
    //初始化读写锁和关键段
    InitializeCriticalSection(&g_cs);
    InitializeSRWLock(&g_srwLock);
    HANDLE hThread[READER_NUM + 1];
    int i;
    //先启动二个读者线程
    for (i = 1; i <= 2; i++)
    hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
    //启动写者线程
    hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);
    Sleep(50);
    //最后启动其它读者结程
    for ( ; i <= READER_NUM; i++)
    hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
    WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE);
    for (i = 0; i < READER_NUM + 1; i++)
    CloseHandle(hThread[i]);
    //销毁关键段
    DeleteCriticalSection(&g_cs);
    return 0;
    }


    • 本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
      本站(WWW.)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
      转载请注明:文章转载自:[169IT-IT技术资讯]
      本文标题:最新Windows下c++读写锁SRWLock介绍
    相关文章推荐:
  • java命名空间java.awt.event类keyevent的类成员方法: vk_windows定义及介绍
  • 怎么在Linux下改windows系统文件啊,我把windows的BOOT.INI改了,windows启动不了
  • WinDows8最新版文件夹加密
  • x-windows如何安装在linux(rdehat9)上面呢,是不是x-windows也分windows和linux版本的吗?
  • 修改Windows硬盘分区名称
  • linux和windows串口问题!?linux向windows端发送,第一次write正常,继续write,windows接收到的就变成乱码了,这是什么原因??????
  • windows10玩游戏怎么样?唯一支持DirectX 12的windows
  • 装了Linux和Windows,怎样默认进入Windows
  • windows/windows 7/windows 8 下打开查看、修改及保存超大(GB级)文本文件及其它类型文件的工具-PilotEdit
  • Linux与windows共存时,如何将Windows设置为默认启动系统?
  • Docker宣布支持Windows 10和Azure Windows Server
  • linux 、 unix给windows传送文件windows
  • win7/Windows7系统下载地址搜集整理
  • 怎样是编好的java application在windows上像windows应用程序一样直接运行
  • Windows7自带防火墙设置:启动,关闭及高级设置
  • windows 和linux双系统,重装windows后,无法启动linux?
  • IE11设置IE兼容性视图及提升Windows 8.1中IE11兼容性的相关设置
  • 如何将linux的一台机器加入windows 2000的域?并且通过一windows的机器上网?
  • Windows优化大师最新版 V7.99 Build 12.604发布
  • 为什么在安装了WINDOWS和LINUX的电脑上,重装WINDOWS会破坏MBR?
  • Windows7 常用使用技巧
  • Linux + Windows2000 双启动,Windows2000起不来了,说是文件被破坏,进来看看……


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3