当前位置: 首页 > news >正文

多线程同步-条件变量

1.简介

当想入写入者线程和读取者线程以独占模式或共享模式访问同一个资源的时候,可以使用SRWLOCK读写锁。

  • 如果读取者线程没有数据可读取,那么它应该将锁释放并等待,直到写入者线程产生了新的数据为止。
  • 如果写入者线程产生的数据写满,那么写入者线程同样应该释放SRWLOCK并进入睡眠状态,直到读取者线程把数据清空为止。

windows通过SleepConditionVariableCS或SleepConditionVariableSRW函数,提供了一种条件变量。

BOOL SleepConditionVariableCS(
  [in, out] PCONDITION_VARIABLE ConditionVariable,
  [in, out] PCRITICAL_SECTION   CriticalSection,
  [in]      DWORD               dwMilliseconds
);
BOOL SleepConditionVariableSRW(
  [in, out] PCONDITION_VARIABLE ConditionVariable,
  [in, out] PSRWLOCK            SRWLock,
  [in]      DWORD               dwMilliseconds,
  [in]      ULONG               Flags
);
  • ConditionVariable:指向一个已初始化的条件变量。
  • 参数2:指向一个关键段或者SRWLock指针。
  • dwMilliseconds:表示希望线程花多少时间来等待条件变量被触发。
  • Flags:指定一旦条件变量被触发,希望线程以何种方式来得到锁:对写入者线程来说,应该传入0,对读取者线程来说,传入CONDITION_VARIABLE_LOCKMODE_SHARED。

当指定的时间用完时候,如果条件变量未被触发,返回FALSE,否则返回TRUE。

当另一个线程检测到相应的条件已经满足的时候,比如有数据可读取了,它会调用下面的函数,阻塞在Sleep*函数中的线程会被唤醒。

    WakeAllConditionVariable();
    WakeConditionVariable();

2.示例

创建两个等待线程,一个苏醒线程,等待几秒后,sets线程,唤醒所有的别的线程。别的线程唤醒后执行结束退出。

// Interlocked.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <windows.h>

DWORD WINAPI sets(LPVOID);
DWORD WINAPI write(LPVOID);


BOOL RUNNING = FALSE;
SRWLOCK  g_srwlock;         //读写同步对象  
CONDITION_VARIABLE g_con;  //条件变量

int main()
{
    HANDLE aThread[3];
    DWORD ThreadID;

    InitializeConditionVariable(&g_con);
    InitializeSRWLock(&g_srwlock);

    //创建多线程
    aThread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)write, NULL, 0, &ThreadID);
    if (aThread[0] == NULL)
    {
        printf("CreateThread error: %d\n", GetLastError());
        return 1;
    }

    aThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)write, NULL, 0, &ThreadID);
    if (aThread[0] == NULL)
    {
        printf("CreateThread error: %d\n", GetLastError());
        return 1;
    }

    aThread[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sets, NULL, 0, &ThreadID);
    if (aThread[0] == NULL)
    {
        printf("CreateThread error: %d\n", GetLastError());
        return 1;
    }


    WaitForMultipleObjects(3, aThread, TRUE, INFINITE);

    // Close thread and mutex handles

    for (int i = 0; i < 3; i++)
        CloseHandle(aThread[i]);

    return 0;

}

DWORD WINAPI write(LPVOID lpParam)
{
    UNREFERENCED_PARAMETER(lpParam);

    AcquireSRWLockExclusive(&g_srwlock);

    if (RUNNING == FALSE)
        SleepConditionVariableSRW(&g_con, &g_srwlock, INFINITE, 0);


    printf("write Thread %d finished...\n",
        GetCurrentThreadId());

    ReleaseSRWLockExclusive(&g_srwlock);

    return 1;
}

DWORD WINAPI sets(LPVOID lpParam)
{
    UNREFERENCED_PARAMETER(lpParam);

    AcquireSRWLockExclusive(&g_srwlock);

    for (int i = 0; i < 100; ++i)
    {
        Sleep(50);
        printf("sets Thread %d wait...\n", GetCurrentThreadId());
    }

   
    ReleaseSRWLockExclusive(&g_srwlock);
    WakeAllConditionVariable(&g_con);

    return 1;
}

 执行结果:

 

相关文章:

  • 视频直播软件哪个好/企业站seo案例分析
  • 深圳开发的购物网站/百度指数的网址是什么
  • 网站建设开发公司微信公众号开发/友情链接搜读
  • 泰安做网站建设的/深圳seo云哥
  • 哪个全球购网站做的好处/关于进一步优化当前疫情防控措施
  • 天津建筑网站建设/新闻头条今日要闻10条
  • JS(第八课)循环语句中常用到的案例
  • 2022软考高项十大领域知识整理(四)-人力资源管理、干系人管理、采购管理
  • 深度学习基础之BatchNorm和LayerNorm
  • 【Spring】面向切面编程详解(AOP)
  • 力扣(LeetCode)75. 颜色分类(C语言)
  • LeetCode算法题整理(200题左右)
  • flowable-ui绘图常见错误
  • 前端最新基础知识
  • 【2022年玄武云科技AI算法岗秋招面试记录】
  • ROBOGUIDE软件:FANUC机器人电弧跟踪功能介绍与示教编程操作
  • 5 个 TypeScript 库来改进你的代码
  • 高校教学管理信息系统/教学管理系统