linux 有名信号量semaphore性能探究

线程池中使用条件变量和信号量的性能比较 面试的时候经常被问到互斥量,条件变量和信号量之间的问题。比如前几天华为面试就被问到互斥量和信号量的区别,说到互斥量也可以使用一个二值信号量来实现,什么情况是只能使用互斥量而不能使用信号量的。这个问题当时我只回答出一种情况,想了解详情的可自行百度。如面试官所说,信号量可以实现互斥量,大部分情况下也可以实现条件变量。甚至使用信号量的实现远比其他实现更容易理解。然而很多时候使用信号量替换条件变量的可能会降低系统性能 阅读详情

起因

最近想基于共享内存加有名信号量实现一个进程间的共享栈,来取代thrift, 优化下ipc的延迟。

测试

首先测试了下thrift消息传递的延迟,分别在client调用前和server(client server位于同一台机器)收到消息打印微秒

start  end    us
776912 777005 93
777152 777228 76
777340 777422 82
777502 777572 70

测试结果表明thrift一次通信大概需要80us的延迟。

如果我们改为信号量来通知server读取共享栈的参数,那么我们有必要测试下信号量在阻塞的情况下,被sem_post唤醒的性能。

贴下测试使用的client 和server代码

 

client

#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>


int main()
{

  sem_t *lock = sem_open("lock_test", O_CREAT | O_RDWR, 0777, 0); 
  int id = 0;
  while(1) {
        sleep(1);
        struct timeval tv; 
        gettimeofday(&tv, NULL);
        sem_post(lock);
        printf("id=%d, usec=%d\n", id, tv.tv_usec);
        id++;
  }
}

server

#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>


int main()
{

  sem_t *lock = sem_open("lock_test", O_CREAT | O_RDWR, 0777, 0); 
  int id = 0;
  while(1) {
        sem_wait(lock);
        struct timeval tv; 
        gettimeofday(&tv, NULL);
        printf("id=%d, usec=%d\n", id, tv.tv_usec);
        id++;
  }
}

 测试结果

client
id=0, usec=279236
id=1, usec=279418
id=2, usec=279542
id=3, usec=279660
id=4, usec=279777
id=5, usec=279902
id=6, usec=280030
id=7, usec=280147
id=8, usec=280261
id=9, usec=280380
id=10, usec=280512
id=11, usec=280635
id=12, usec=280748
id=13, usec=281623
id=14, usec=281731
id=15, usec=281854
id=16, usec=281991
id=17, usec=282119
id=18, usec=282240
id=19, usec=282353
id=20, usec=282471
id=21, usec=282604
id=22, usec=282719

server
id=0, usec=279284
id=1, usec=279445
id=2, usec=279569
id=3, usec=279693
id=4, usec=279810
id=5, usec=279942
id=6, usec=280060
id=7, usec=280176
id=8, usec=280293
id=9, usec=280413
id=10, usec=280547
id=11, usec=280665
id=12, usec=280773
id=13, usec=281679
id=14, usec=281764
id=15, usec=281910
id=16, usec=282024
id=17, usec=282166
id=18, usec=282287
id=19, usec=282379
id=20, usec=282520
id=21, usec=282638
id=22, usec=282747

测试发现信号量在阻塞的情况下被唤醒,需要大概20-40个us的时间(猜测涉及到了linux内核的调度)。

总结

基于上述结果,综合了下实际情况,没有改造的必要。首先自己实现协议栈的解析,会带来延迟。并且所有的client都需要被改造,最重要的是,操作栈的时候,要锁住共享栈,导致并发数将为1。通过这次测试对信号量的性能心中有底了。

【mutex、读写锁、自旋锁、信号量以及RCU的性能测试】 自旋锁特点 循环等待等 力度很小 用于链表头指针改变等情况 mutex 加锁时线程休眠一会看一下 可用于大部分情况 读写锁 读写都要判断 加锁复杂 不推荐使用 信号量 pv操作 比mutex低一点 rcu 读写锁变种 read copy update 可以代替读写锁情况... 阅读详情

相关推荐

Linux内核参数-共享内存信号量semaphore设置

共享内存: 可以通过ipcs -lm命令查看目前系统共享内存的参数限制: # ipcs -lm —— Shared Memory Limits ——– max number of segments = 4096 max seg size (kbytes) = 1048576 max total shared memory (pages) = 2097152 min seg size

xabc3000的专栏 9089

信号量,锁,CAS,原子变量,多线程的性能问题简单测试。

对于CAS和原子变量来说,此二者都属于无锁编程效率比使用锁的方式保证同步性能肯定是要好一些。信号量可以看成属于锁的一种,效率相对来说比较低一些。可以看出来锁的效率相对要低很多,原子变量效率比较高,但是很多场景使用起来比较困难,cas有经典的ABA问题,编程时候根据具体情况进行选择。根据下面的测试结果可以得出耗时排名 锁 > 信号量 > CAS > 原子变量。共耗时:1.34078 ms。共耗时:0.453776 ms。共耗时:3.02758 ms。共耗时:1.69192 ms。...

weixin_42317175的博客 805

四、读写信号量(rw_semaphore)

读写信号量对访问者进行了细分,或者为读者,或者为写者,读者在保持读写信号量期间只能对该读写信号量保护的共享资源进行读访问,如果一个任务除了需要读,可能还需要写,那么它必须被归类为写者,它在对共享资源访问之前必须先获得写者身份,写者在发现自己不需要写访问的情况下可以降级为读者。读写信号量同时拥有的读者数不受限制,也就说可以有任意多个读者同时拥有一个读写信号量。   如果一个读写信号量当前没有被

兰宝的专栏 1579

linux线程间同步信号量semp性能,dispatch_semaphore_t信号量

开发当中我们经常会碰到这种情况:假设现在系统有两个空闲资源可以被利用,但同一时间却有三个线程要进行访问,这种情况下,该如何处理呢?我们要下载很多图片,并发异步进行,每个下载都会开辟一个新线程,可是我们又担心太多线程肯定cpu吃不消,那么我们这里也可以用信号量控制一下最大开辟线程数。1.定义:就是一种可用来控制访问资源的线程数量的标识,设定了一个信号量,在线程访问之前,加上信号量的处理,则可告知系统...

weixin_35626077的博客 511

Linux下从信号量看线程调度时间

前几天写了一篇文章关于Linux下进程调度时间的,本意是想测试下实时性能的,包括中断响应时间等等,这个可能需要借助于硬件发出终端来测试, 那片文章是讲的是通过发送信号给另一个进程,然后测量发送信号到进入信号处理程序之间的时间 信号只是针对进程来说的,今天讲的主要是通过信号量semaphore来测试一下线程间切换的时间 首先看下基础知识: 1.

三哥的技术专栏 1384

Linux之信号量_很全面的分析_个人整理的

Linux之信号量_很全面的分析_个人整理的

记录锁、信号量、互斥量区别与时间性能比较

一、记录锁 1、概念 我们首先来看记录锁,记录锁的功能是当一个进程正在读或者修改文件的某一个部分时,它可以阻止其他进程修改同一文件区。它其实是“字节范围锁”,因为它锁定的是文件中的一个区域,当然,也可能是整个文件。如下图: 记录锁其实是不同进程间进行同步的一种锁...

weixin_33711647的博客 556

SAP FICO CK40N批量发布标准价:常见报错排查与实战解决指南

本文详细解析了SAP FICO模块中CK40N批量发布标准价的常见报错及解决方案。从物料选择、成本核算到最终发布的全流程,提供了针对'已有标准成本估算记号'等典型报错的实战处理技巧,并分享了预防性维护与批量处理的高效方法,帮助财务人员提升工作效率。

weixin_29234509的博客 304

信号量(Semaphore)

首选 C++20 标准库:如果你能使用支持 C++20 的编译器(GCC 11+, Clang 11+, MSVC 19.28+),请直接使用 <semaphore>,性能最好且跨平台。遗留系统使用 std::mutex + std::condition_variable:如果必须在旧标准下工作,使用第二部分提供的封装类。避免使用原生的操作系统 API。

我的博客主要是用来给我自己复习的,主要是上传一些知识点,小型的项目和功能模块,如果有什么问题或错误麻烦联系我! 1120

手把手教你复现IEEE 2025高光谱图像盲超分算法DBSR(附开源代码与避坑指南)

本文详细介绍了如何从零复现IEEE 2025高光谱图像盲超分算法DBSR,包括环境配置、数据预处理、核心模块解析、训练策略及常见问题解决方案。特别针对开源代码中的关键步骤和潜在问题提供了实用指南,帮助研究者和开发者高效实现Deep blind super-resolution技术,适用于遥感、医疗等领域的图像增强应用。

weixin_42524708的博客 411

STM32F103C8T6驱动DHT11温湿度传感器程序

本程序基于 STM32F103C8T6 微控制器,通过 GPIO 模拟单总线通信时序实现对 DHT11 温湿度传感器的数据采集,主机采用拉低数据线的方式触发传感器启动,并通过检测高电平持续时间区分逻辑“0”和“1”,依次读取湿度和温度的整数数据及校验位,经过校验后将有效结果存入缓存数组,实现对环境温湿度的周期性测量与处理。

加斯顿工程师的博客 200

【Linux内核】信号量semaphore机制

信号量机制是一种用于控制并发访问的同步机制,常用于多进程或多线程之间的协调。在Linux内核中,信号量机制是通过struct semaphore结构体来实现的。每个semaphore结构体包含一个计数器和一个等待队列,它们用于跟踪当前可用的资源数量以及正在等待这些资源的进程或线程。当某个进程或线程需要访问共享资源时,它会先尝试获取信号量。如果信号量的计数器大于0,表示有可用的资源,该进程或线程就可以继续执行,并将信号量计数器减1;

逆风水手的博客 2382

apollo-减速带通行

主车在通过减速带时速度不超过3m/s

是菜鸟o的博客 389

linux源码之信号量(semaphore/rw_semaphore )分析

本文以linux-4.14.159 kernel代码进行研究分析 信号量semaphore机制是以 一. 信号量 结构体 struct semaphore { raw_spinlock_t lock; unsigned int count; struct list_head wait_list; }; 二. 读写信号量

jkzzxQQQ的博客 1502

移位寄存器——用Verilog实现串入串出、串并和并串转换并进行Modelsim仿真

用Verilog实现串并转换 首先我们先要了并串和串并转换的原理 并串转换:先将八位数据暂存于一个八位寄存器器中,然后左移输出到一位输出端口,这里可以通过一个“移位”来实现,相当于实现了移位寄存器的功能。 串并转换:新输入的位值成为原来数据的最低位,将原来数据的最高位舍去,这里可以通过一个简单的“连接符”来实现。 我们这里采用两种方式来进行串并转换 一:lsb优先 Least Significant Bit,最低比特,最低位优先 二:msb优先 Most Significant Bit,最高比特,

H19981118的博客 2万+

【小白深度教程 1.3】使用 BP-Net 深度补全网络,进行 KITTI 稠密点云和图像融合(Depth Completion 实战)

在上一节中,我们展示了如何将从激光雷达获取的稀疏点云(深度)映射到图像。因此这篇论文我们尝试使用 Depth Completion(深度补全)技术,来将稀释的点云深度,补全为稠密深度。

2401_87064292的博客 1198

C++ 的信号量(semaphore)

C++ 20 引入 std::counting_semaphore 和 std::binary_semaphore,对操作系统的原生信号量提供了一致的封装,通过操作系统提供的高效实现(linux 上用 futex,Windows 上用 WaitOnAddress/SRWLock),有比 mutex + condition_variable 的方案更好的性能。C++ 没有信号量!mutex 有一个限制,也可以说是一个特性,就是锁的申请和释放必须是同一个线程,也就是在一个线程申请的锁,必须在这个线程中释放。

2501_93283929的博客 682

PCL Super4PCS算法实现点云粗配准(版本一)【2025最新版】

Win11系统下实现[Super4PCS: Fast Global Pointcloud Registration via Smart Indexing一文中的配准算法。

点云侠的博客 3378

linux spin_lock(自旋锁)semaphore(信号量)和mutex(互斥锁)的区别

1 spin_lock        自旋锁的实现是为了保护一段短小的临界区操作代码,保证这个临界区的操作是原子的,从而避免并发的竞争冒险。在Linux内核中,自旋锁通常用于包含内核数据结构的操作,你可以看到在许多内核数据结构中都嵌入有spinlock,这些大部分就是用于保证它自身被操作的原子性,在操作这样的结构体时都经历这样的过程:上锁-操作-解锁。       如果内核控制路径发现自旋锁“...

D_Guco的专栏 4114

安卓开发工程师在车载项目中的角色与技术实践

本文全面探讨了安卓开发工程师在车载项目中的关键角色,重点分析了技术栈(Kotlin/Java/Gradle)、岗位职责和任职要求。文章详细解读了车载安卓开发的核心技能,包括架构设计、性能优化和缺陷修复,并提供了20个针对性面试问题及答案。特别强调了车载环境的特殊需求,如硬件集成、安全认证和实时性要求。通过技术深度与实践案例的结合,为开发者和企业提供了从需求分析到系统优化的完整指导,旨在提升车载安卓开发的专业水平和招聘效率。

郑伟强dev的专栏 131

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

linux eventfd事件通知 比信号量更好用

本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。eventfd 就是一个用于事件通知的fd。当然linux中,一切都可以做为文件来看待,所以就有fd。这样有一个好处管理统一,比如可以加入到epoll事件等待中。很多人可能没怎么用,但是用过的人都说:香!eventfd 提供了一个进程/线程间通信的方式。这个方式是载体是一个句柄,也就是fd,类型是eventfd,可以在/proc下查看fd时看到;

一个追逐梦想的码农 7244

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

设备驱动之一 - linux读写信号量semaphore .

读写信号量(rw_semaphore)   读写信号量对访问者进行了细分,或者为读者,或者为写者,读者在保持读写信号量期间只能对该读写信号量保护的共享资源进行读访问,如果一个任务除了需要读,可能还需要写,那么它必须被归类为写者,它在对共享资源访问之前必须先获得写者身份,写者在发现自己不需要写访问的情况下可以降级为读者。读写信号量同时拥有的读者数不受限制,也就说可以有任意多个读者同时拥有一个读

宇宙的起源 857

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux进程间通信IPC深度精讲,匿名/有名管道、共享内存、消息队列、信号量原理、代码实战、性能对比与工程选型

我们彻底吃透了Linux进程全套原理,掌握了fork进程创建、COW写时复制、僵尸/孤儿进程处理、进程资源继承与回收机制。进程拥有独立虚拟地址空间,进程与进程之间数据完全隔离。这就带来了服务端开发的核心痛点:多进程架构下,父子进程、兄弟进程无法直接访问彼此数据。但在实际工程中,日志收集、任务分发、数据缓存、多进程任务并行,都需要进程之间高效传输数据、同步执行顺序、竞争资源。为此Linux内核提供了一套标准化的IPC(Inter-Process Communication,进程间通信)机制。

2401_86195313的博客 187

linux 信号量_Linux学习第29节,从C语言源码分析,信号量和自旋锁有何区别

上一节主要介绍了Linux内核中的自旋锁,知道了自旋锁是不能睡眠的,因此只适合用于短时间的保护临界区。如果需要较长时间的持有锁,就不应该再使用自旋锁了,因为这会大量消耗 cpu 的性能,大大降低整个系统的效率。不过,在Linux内核开发中,不可避免的会遇到需要长时间保护的临界区,该怎么办呢?因此,Linux 内核还提供了一种同步共享数据的机制——信号量。信号量在 1968 年由计算机科学家 Eds...

weixin_39936388的博客 89

linux线程间同步信号量semp性能,线程间通信:Condition | 信号量:Semaphore

线程间通信:Condition对于线程间通信,大家最熟悉的莫过于Object.wait()、Object.notify()了。Condition的使用与前面的方法类似。void await() throws InterruptedException;void awaitUninterruptibly();long awaitNanos(long nanosTimeout) throws Inter...

weixin_42361834的博客 265

内核同步机制-读写信号量(rw_semaphore)

四、读写信号量(rw_semaphore) 读/写信号量适于在读多写少的情况下使用。如果一个任务需要读和写操作时,它将被看作写者,在不需要写操作的情况下可降级为读者。任意多个读者可同时拥有一个读/写信号量,对临界区代码进行操作。 在没有写者操作时,任何读者都可成功获得读/写信号量进行读操作。如果有写者在操作时,读者必须被挂起等待直到写者释放该信号量。在没有写者或读者操作时,写者必须等待前面

wangpengqi的专栏 1万+
上一篇: muduo 中 has_no_destroy 模板
下一篇: linux inotify 触发点探秘
Sweet_Oranges
博客等级 码龄12年 1粉丝 20原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值