12-6 锁

2023-11-04

        加锁可保证原子性操作和共享资源的可见性,但加锁成本相对较高。

        mingw 编译器下,可用 mtx_t 定义一个锁,mtx_init() 函数初始化一个锁,mtx_destory() 函数销毁一个锁,mtx_lock() 函数加锁,mtx_lock() 函数解锁。

        mtx_timedlock() 函数和 mtx_lock() 函数功能类似,mtx_lock()函数加锁不成功时会一直等待,而 mtx_timedlock() 函数加锁不成功时可设置等待时间。mtx_trylock() 尝试加锁,加锁成功返回锁,加锁不成功也不等待,直接返回不成功。

        锁有三种类型,mtx_plain 普通锁,不支持设置等待时间。mtx_timed 智能锁,支持设置等待时间。mtx_recursive 递归锁,可以递归使用这个锁。

#include <stdio.h>
#include <time_utils.h>
#include <tinycthread.h>
#include <stdatomic.h>

typedef int (*Test)(void);  // 定义函数指针 Test 类型,可指向任意参数 void 返回值为 int 的函数

// 通过函数指针调用不同函数去执行
void TestTimeInMillisecond(Test test){

  long_time_t start_time = TimeInMillisecond();

  test();

  long_time_t end_time = TimeInMillisecond();

  printf("times: %lld\n", end_time - start_time);  // times: 197
}

// 使用原子类型进行 count++
atomic_int count_atomic = 0;
int CounterAtomic(void *arg){
  for (int i = 0; i < 1000000; ++i) {
    count_atomic++;
  }
  return 0;
}

int TestCounterByAtomic(){
  thrd_t t_1;
  thrd_t t_2;

  // create two threads to run the Counter function
  thrd_create(&t_1, CounterAtomic, NULL);
  thrd_create(&t_2, CounterAtomic, NULL);

  // free up resources
  thrd_join(t_1, NULL);
  thrd_join(t_2, NULL);

  printf("count_atomic: %d\n", count_atomic);  // count: 1049042

  return 0;
}

// 使用锁进行 count++
int count_lock = 0;
mtx_t mutex;  // 定义一个锁

int CounterLock(void *arg){

  for (int i = 0; i < 1000000; ++i) {
    mtx_lock(&mutex);
    count_lock++;
    mtx_unlock(&mutex);
  }
  return 0;
}

void TestCounterByLock(){
  thrd_t t_1;
  thrd_t t_2;

  // create two threads to run the Counter function
  thrd_create(&t_1, CounterLock, NULL);
  thrd_create(&t_2, CounterLock, NULL);

  // free up resources
  thrd_join(t_1, NULL);
  thrd_join(t_2, NULL);

  printf("count_lock: %d\n", count_lock);
  mtx_destroy(&mutex);
}

int main(){

  // 查看原子类型消耗的时间
  Test test_atomic = TestCounterByAtomic;
  TestTimeInMillisecond(test_atomic);

  // 加锁耗费的时间
  mtx_init(&mutex, mtx_plain);  // 初始化锁
  Test test_lock = TestCounterByLock;
  TestTimeInMillisecond(test_lock);

  return 0;
}

         注意,代码书写过程中使用了函数指针,将函数作为参数传入到其它函数中使用。可将其看做对象去理解,一个函数中需要执行两个对象的方法,这两个对象的类型是一致的,故传入参数应为对象,再去执行传入对象中的方法。类比于函数指针,两个函数的结构是一样的,所以可用函数指针去替代两个函数,之后执行该函数指针指向的方法即可。程序执行结果如下图所示,可以发现加锁的性能消耗大于操作 atomic_int 定义的原子类型变量

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

12-6 锁 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new

随机推荐

  • 宝塔:MySQL无法启动解决方案/www/server/mysql/bin/mysqld: Shutdown complete

    宝塔 MySQL无法启动解决方案 www server mysql bin mysqld Shutdown complete MySQL版本5 5 故障现象 MySQL无法启动 报错信息如下 190228 9 19 43 ERROR Can
  • pyltp安装

    我们在做依存句法分析时候会用到这个包 直接pip install conda install可能会报错 今天就讲讲这块 需要的小伙伴跟着我操作哦 1 首先我们要搞清楚自己python的版本是多少 打开这个 输入python可以查找版本号 这
  • sqlserver分页存储过程

    分页存储过程 if OBJECT ID proc page P is not null drop proc proc page go create proc proc page tabName varchar 2000 fieldStr v
  • 媲美postman?这款国产测试工具你知道吗

    没有测试数据的用例就像一盘散沙 跑两步就跑不动了 没有测试数据 所谓的功能测试和性能测试全都是无米之炊 但我发现一个蛮诡异的事情 就是行业内很少会有人去强调测试数据的重要性 甚至市面上都没有人在做测试数据这门生意 至今测试er造测试数据还是
  • Python协程学习--爬取一本网络小说

    协程爬取 最近在学习Python爬虫 同时在公司同事的引导下接触到协程 开始学习使用协程编写异步爬虫 Python协程系列学习参考 https blog csdn net qq 27825451 article details 862182
  • Elasticsearch快速入门之狂薅官网系列之Aggregations-聚合(3)

    本文为翻译官网 Aggregations 部分但有一定改动之后的文章 官网地址 https www elastic co guide en elasticsearch reference 7 3 search aggregations ht
  • Android 5,kotlin循环for

    Unless required by applicable law or agreed to in writing software distributed under the License is distributed on an AS
  • LZW编解码算法原理及分析

    文章目录 数据压缩实验 三 一 LZW概述 二 LZW编解码原理 1 LZW编码 1 算法原理 2 算法流程 2 LZW解码 1 算法原理 2 算法流程 3 实验过程 1 数据结构分析 2 主函数 3 主要功能模块 4 实验结果 总结与分析
  • #ifndef 和#pragma once

    作用 为了避免同一个文件被include多次 C C 中有两种方式 一种是 ifndef方式 一种是 pragma once方式 在能够支持这两种方式的编译器上 二者并没有太大的区别 但是两者仍然还是有一些细微的区别 方式一 ifndef
  • 代码审计——BruteForce

    Low级别 源码 1 首先通过isset 函数判断是否接收到了GET型的Login的值 接收到了代表用户提交了数据 isset 函数 在实际开发中 isset 通常用于快速检查某个变量是否存在或为空 并且可以帮助避免一些未定义变量引起的错误
  • Vscode-Latex 报错 I found no \bibdata command

    问题描述 原本使用的是 bib文件引用文献 后来觉得不方便 不如写在文末 改用 bibitem 然后使用pdflatex gt bibtex gt pdflatex 2进行编译 接着报错 I found no bibdata command
  • 编译原理 --- NFA(非确定有限自动机)和DFA(确定有限自动机)之间的转换以及DFA的化简

    第一部分 证明NFA能够转换为DFA 1 So是NFA的初态集合 F是NFA的终态集合 2 通过上面的第一个转换 我们就使得NFA具有了和DFA一样的唯一初态 3 通过上面的第二个转换 不断引入中间状态 直到将字拆分为字符 此时我们就成功的
  • 日常工作中需要注意的Java编码规范

    经常听到 编码风格 这个词 那么什么是编码风格呢 接手项目后 读项目中其他人的代码 你就能感觉到不同编码风格 有的人写的代码很乱 可读性很差 方法逻辑处理耦合度很高 缩进不规范 有的人编码风格很好 代码缩进对齐看起来很规范 注释清晰 这就是
  • Python小屋在线练习与刷题软件重要升级

    开学第一课 一定不要这样问老师Python问题 中国大学MOOC Python程序设计基础 第6次开课时间 董付国老师Python系列教材推荐与选用参考 2022年4月13日 Python小屋刷题软件进行了升级 停用之前版本的客户端 请后台
  • matlab直方图显示,控制分类直方图的显示

    创建分类直方图 示例文件 outages csv 包含表示美国电力中断情况的数据 该文件包含六个列 Region OutageTime Loss Customers RestorationTime 和 Cause 以表的形式读取 outag
  • OpenGL基础知识梳理——Windows上搭建opengles运行环境

    1 概念介绍 1 OpenGLES 官方介绍 https www khronos org opengles OpenGLES OpenGL for embeded systems 是用于嵌入式设备的免费 跨平台的2D 3D渲染API 它是O
  • C++中cout、cin和endl的用法

    转自 http blog csdn net zhanghaotian2011 article details 8868577 转自 http blog csdn net u011675745 article details 51939108
  • 【最详细

    软件下载 软件 Visual C 版本 6 0 语言 简体中文 大小 34 26M 安装环境 Win11 Win10 Win8 Win7 硬件要求 CPU 2 0GHz 内存 4G 或更高 下载通道 百度网盘丨下载链接 https pan
  • 微信公众号开发《五》基于Java实现微信支付(公众号支付)简单教程

    最近公司需求 需要在微信公众号内完成支付 找到官方文档 文档还可以 讲的也挺详细 不过有一个地方很坑爹 就是微信内H5调起支付需要一个签名 而他给出的参考签名方式跟统一下单签名一致 害的我以为 他这个签名就是统一下单那个签名 后面找了很久看
  • 12-6 锁

    加锁可保证原子性操作和共享资源的可见性 但加锁成本相对较高 mingw 编译器下 可用 mtx t 定义一个锁 mtx init 函数初始化一个锁 mtx destory 函数销毁一个锁 mtx lock 函数加锁 mtx lock 函数解