专栏首页C++Windows核心编程:第8章 用户模式下的线程同步

Windows核心编程:第8章 用户模式下的线程同步

Github

https://github.com/gongluck/Windows-Core-Program.git

//第8章 用户模式下的线程同步.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "第8章 用户模式下的线程同步.h"

LONG g_i = 100;
LONG g_b = FALSE;

CRITICAL_SECTION g_cs; //关键段
SRWLOCK g_rw; //读写锁
CONDITION_VARIABLE g_cv; //条件变量


DWORD WINAPI Thread1(PVOID param)
{
    for (int i = 0; i < 100; ++i)
    {
        EnterCriticalSection(&g_cs);
        g_i += i;
        LeaveCriticalSection(&g_cs);
    }
    return 0;
}

DWORD WINAPI Thread2(PVOID param)
{
    for (int i = 0; i < 100; ++i)
    {
        if (TryEnterCriticalSection(&g_cs))
        {
            g_i += i;
            LeaveCriticalSection(&g_cs);
        }
        else
            SwitchToThread();
    }
    return 0;
}

DWORD WINAPI Thread3(PVOID param)
{
    for (int i = 0; i < 100; ++i)
    {
        AcquireSRWLockExclusive(&g_rw);
        //写
        OutputDebugString(TEXT("------------AcquireSRWLockExclusive succeed.\n"));
        ReleaseSRWLockExclusive(&g_rw);
    }
    return 0;
}

DWORD WINAPI Thread4(PVOID param)
{
    for (int i = 0; i < 100; ++i)
    {
        AcquireSRWLockShared(&g_rw);
        //读
        OutputDebugString(TEXT("------------AcquireSRWLockShared succeed.\n"));
        ReleaseSRWLockShared(&g_rw);
    }
    return 0;
}

DWORD WINAPI Thread5(PVOID param)
{
    int n = 0;
    for (int i = 0; i < 100; ++i)
    {
        EnterCriticalSection(&g_cs);
        ++n;
        if (n >= 100)
            break;
        if(g_i <= 0)
            SleepConditionVariableCS(&g_cv, &g_cs, INFINITE); //解锁等待条件变量,返回时再加锁
        g_i--;
        LeaveCriticalSection(&g_cs);
    }
    return 0;
}

DWORD WINAPI Thread6(PVOID param)
{
    for (int i = 0; i < 100; ++i)
    {
        if (TryEnterCriticalSection(&g_cs))
        {
            g_i++;
            WakeConditionVariable(&g_cv); //唤醒等待条件变量的线程
            LeaveCriticalSection(&g_cs);
        }
        else
            SwitchToThread();
    }
    return 0;
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    //原子操作Interlocked系列
    LONG newl = InterlockedAdd(&g_i, 1);
    LONG oldl = InterlockedExchange(&g_i, 10);
    oldl = InterlockedCompareExchange(&g_i, 100, 10);
    LONGLONG oldll = InterlockedAnd(&g_i, 0x0001);

    //旋转锁!
    while (InterlockedExchange(&g_b, TRUE) == TRUE)
        Sleep(0);

    //使用关键段
    //InitializeCriticalSection(&g_cs);
    BOOL bret = InitializeCriticalSectionAndSpinCount(&g_cs, 1);//初始化关键段并用上旋转锁
    oldl = SetCriticalSectionSpinCount(&g_cs, 4000);
    g_i = 0;
    HANDLE hthread1 = CreateThread(nullptr, 0, Thread1, nullptr, 0, nullptr);
    HANDLE hthread2 = CreateThread(nullptr, 0, Thread2, nullptr, 0, nullptr);

    WaitForSingleObject(hthread1, INFINITE);
    WaitForSingleObject(hthread2, INFINITE);
    CloseHandle(hthread1);
    hthread1 = nullptr;
    CloseHandle(hthread2);
    hthread2 = nullptr;

    //使用读写锁
    InitializeSRWLock(&g_rw);
    HANDLE hthread3 = CreateThread(nullptr, 0, Thread3, nullptr, 0, nullptr);
    HANDLE hthread4 = CreateThread(nullptr, 0, Thread4, nullptr, 0, nullptr);

    WaitForSingleObject(hthread3, INFINITE);
    WaitForSingleObject(hthread4, INFINITE);
    CloseHandle(hthread3);
    hthread3 = nullptr;
    CloseHandle(hthread4);
    hthread4 = nullptr;

    //条件变量(误入锁?)
    InitializeConditionVariable(&g_cv);
    g_i = 0;
    HANDLE hthread5 = CreateThread(nullptr, 0, Thread5, nullptr, 0, nullptr);
    HANDLE hthread6 = CreateThread(nullptr, 0, Thread6, nullptr, 0, nullptr);

    WaitForSingleObject(hthread5, INFINITE);
    WaitForSingleObject(hthread6, INFINITE);
    CloseHandle(hthread5);
    hthread5 = nullptr;
    CloseHandle(hthread6);
    hthread6 = nullptr;

    DeleteCriticalSection(&g_cs);

    system("pause");
    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Windows核心编程:第9章 用内核对象进行线程同步

    https://github.com/gongluck/Windows-Core-Program.git

    gongluck
  • Windows核心编程:第10章 同步设备IO与异步设备IO

    https://github.com/gongluck/Windows-Core-Program.git

    gongluck
  • FFmpeg4.0笔记:封装ffmpeg的视频帧转换功能类CSws

    https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff

    gongluck
  • 随心所欲对指定R包进行升级与降级

    很多时候,我们其实并不需要动R本身的版本,可能只是想修改某个R包版本,比如单细胞领域最火的 Seurat 包, 就有这个问题:

    生信技能树
  • [机器学习必知必会]凸优化

    凸优化问题(OPT,convex optimization problem)指定义在凸集中的凸函数最优化的问题。尽管凸优化的条件比较苛刻,但仍然在机器学习领域有...

    TOMOCAT
  • memcpy()

    青木
  • Python名词解释

    tonglei0429
  • 练习题三

    第1章 练习题 1.1 第1题 取得/etc/hosts 文件的权限 如何取得/etc/hosts 文件的权限对应的数字内容,如-rw-r--r--  为 64...

    惨绿少年
  • 图解KVM安装CentOS7.6操作系统

    近日服务器安装了CentOS7.6系统,装了KVM,想装Linux虚拟服务器使用。本文图解说明KVM安装CentOS7.6操作系统的过程(介绍图形界面安装方式。...

    技术训练营
  • Windows核心编程:第11章 Windows线程池

    https://github.com/gongluck/Windows-Core-Program.git

    gongluck

扫码关注云+社区

领取腾讯云代金券