Linux---C/C++编程:syscall(系统调用)、SYS_gettid在muduo库中的使用以及static_cast

一、概念

系统调用与用户自定义函数相同,属于一个函数,但是系统调用运行在内核态,而用户自定义函数运行在用户态。由于某些指令(如设置时钟、关闭/打开中断和I/O操作等)只能运行在内核态,所以操作系统提供了系统调用这样的机制,使用户能够进入内核态。
实际上,系统调用 是 Linux 内核提供的一段代码(函数),其实现了一些特定的功能,用户可以通过 int 0x80 中断(x86 CPU)或者 syscall 指令(x64 CPU)来调用 系统调用。 内核提供用户空间程序与内核空间进行交互的一套标准接口,这些接口让用户态程序能受限为了保证内核稳定性,而不能让用户空间程序随意更改系统,必须是内核对外开放的且满足权限的程序才能调用相应接口)访问硬件设备,比如申请系统资源,操作设备读写,创建新进程等。用户空间发生请求,内核空间负责执行,这些接口便是用户空间和内核空间共同识别的桥梁。
Syscall(系统调用, system call)就是连接用户态和内核态的桥梁。这样即提高了内核的安全型,也便于移植,只需实现同一套接口即可。Linux系统,用户空间通过向内核空间发出Syscall,产生软中断,从而让程序陷入内核态,执行相应的操作。对于每个系统调用都会有一个对应的系统调用号,比很多操作系统要少很多。

二、实战

在linux下每一个进程都一个进程id,类型pid_t,可以由 getpid()获取。
POSIX(可移植操作系统接口)线程也有线程id,类型pthread_t,可以由 pthread_self()获取,线程id由线程库维护。
但是每个进程是独立的,所以会有不同进程中线程号相同的情况。那么若进程p1中的线程pt1要与进程p2中的线程pt2通信,就会存在进程id不重复,而线程id可能重复的状态,所以就需要一个真实的线程id唯一标识,tid。glibc(Linux 下的 C 函数库)没有实现gettid的函数,所以可以通过linux下的系统调用 syscall(SYS_gettid) 来获得。

#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syscall.h>
pid_t gettid(void) {return (pid_t)syscall(SYS_gettid);
}
int main()
{printf("%d", gettid());
}

muduo库中的使用

t_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid)); 

在muduo库中,我们在CurrentThread中可以看到使用系统调用获取当前线程的tid。

补充一点static_cast

static_cast 是 C++ 中四个命名强制类型转换操作符之一。它用于执行各种不同类型之间的转换。相对于 C 风格的强制转换(如 (int)3.14),static_cast 更加明确和可读;并且 static_cast 只能执行明确允许的转换,有助于避免一些错误。

一般在以下场景中使用:
  • 基础数据类型的转换,例如:double转int
double d = 5.5;
int i = static_cast<int>(d);  // i = 5
  • 指向派生类的指针或引用转换为指向基类的指针或引用
class Base {};
class Derived : public Base {};
Derived derivedObj;
Base* basePtr = static_cast<Base*>(&derivedObj);
  • 指向基类的指针或引用转换为指向派生类的指针或引用,但是不安全,因为在转换过程中没有运行时检查。如果确实需要运行时检查,应使用 dynamic_cast。
Base* basePtr = new Base();
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 不安全!
  • 在有关联的类型之间进行转换
enum Color { RED, GREEN, BLUE };
int value = static_cast<int>(GREEN);  // value = 1
限制
  • 不能用于转换不相关的指针或引用类型。例如,不能将 void* 转换为其他类型的指针,或反之。在这种情况下,应使用 reinterpret_cast。

  • 不能用于移除或添加 const 限定符。在这种情况下,应使用 const_cast。

参考文章链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/834284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ libtorch使用cmake建立

如果我们安装好pytorch&#xff0c;其实不一定一定要安装libtorch&#xff0c;默认都已经安装过了 1 进入pytorch conda env list conda activate pytorch 命令行下使用 python -c 来获取libtorch的基本信息&#xff0c; python -c "import torch;print(torch.utils.c…

区块链的可扩展性三难问题

这个词是由以太坊的联合创始人Vitalik Buterin创造的&#xff0c;并提出了理想的区块链需要具备的三个特征&#xff1a;去中心化、可扩展性和安全性。 Vitalik还提出&#xff0c;区块链几乎不可能很好地实现所有这三个特征&#xff0c;所以会出现权衡。 因此&#xff0c;今天…

Android使用itextpdf操作PDF文档

1、导入jar包&#xff1a; itext-asian.jaritextpdf-5.5.8.jar Paragraph 和 Phrase 的区别&#xff1a; 在 iTextPDF 库中&#xff0c;Paragraph 和 Phrase 是用于创建和组织文本内容的两个不同的类。 Paragraph&#xff08;段落&#xff09;&#xff1a; Paragraph 是一个…

static静态成员变量和静态方法

当有new创建一个对象的,里面属性和方法,通过构造函数,能定义多个不同的对象,在我们做面向对象开发的时候,给一个场景,人在一个班级的时候,你的老师可能是固定的。 当我们用构造方法去构造的时候&#xff0c;每次都去传递一个固定的实参去定义个老师。 这样好会显得代码非常的…

SOCKET编程(1):基本概念

基本概念 socket分类 socket提供了**流(stream)和数据报(datagram)**两种通信机制&#xff0c;即流socket和数据报socket 流socket基于TCP协议&#xff0c;是一个有序、可靠、双向字节流的通道&#xff0c;传输数据不会丢失、不会重复、顺序也不会错乱 数据报socket基于UDP…

通过父类定义日志输出

1、定义基类&#xff1a; public class BaseController {public Class clazz null;public Logger log null;{clazz this.getClass();log LoggerFactory.getLogger(clazz);} } 2、子类统一继承该基类&#xff1a; RestControllerpublic class AAAController extends Base…

Powerdesigner导入mysql8之后注释丢失

目录 一、问题描述及解决思路 二、导入的步骤 1.先按正常步骤建立一个物理数据模型 &#xff08;1&#xff09;点击“文件-新建模型” &#xff08;2&#xff09;选择物理模型和数据库 2.从sql文件导入表 &#xff08;1&#xff09;点击“数据库-Update Model from Data…

【Redis7】10大数据类型之Set类型

文章目录 1.Set类型2.常用命令&#xff1a;3.示例3.1 SADD,SMEMBERS和SISMEMBER3.2 SREM和SCARD3.3 SRANDMEMBER和SPOP3.4 SMOVE 4.集合运算相关命令4.1 集合交集 (SINTER)4.2 集合并集 (SUNION)4.3 集合差集 (SDIFF)4.4 Redis7新命令sintercard 1.Set类型 Redis的Set类型是一…

正则表达式-前瞻和后顾

正则表达式中的前瞻和后顾。 前瞻(Lookahead) 前瞻是一种断言,它会检查在当前位置之后是否存在某种模式,但不会实际匹配该模式。前瞻有两种形式: 正向前瞻 (?pattern) 检查当前位置之后是否存在指定的模式如果存在,则匹配成功,但不会消耗该模式例如 \w(?\d) 将匹配后面跟数…

RAG 场景对Milvus Cloud向量数据库的需求

虽然向量数据库成为了检索的重要方式,但随着 RAG 应用的深入以及人们对高质量回答的需求,检索引擎依旧面临着诸多挑战。这里以一个最基础的 RAG 构建流程为例:检索器的组成包括了语料的预处理如切分、数据清洗、embedding 入库等,然后是索引的构建和管理,最后是通过 vecto…

【Redis7】10大数据类型之Bitmap类型

文章目录 1.Bitmap(位图)2.常用命令3.示例3.1 SETBIT和GETBIT3.2 STRLEN3.3 BITCOUNT3.4 BITOP 1.Bitmap(位图) Redis的Bitmap类型并不是一个独立的数据类型&#xff0c;而是对String类型的一种巧妙使用&#xff0c;允许开发者以位级别操作字符串中的数据。Bitmap可以视为一个…

学习笔记:【QC】Android Q : telephony-phone 模块

一、phone init 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 二、phone MO 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 三、phone MT 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以…

MySQL慢查询优化【二】

当处理MySQL慢查询优化时&#xff0c;通常需要考虑以下几个方面&#xff1a; 索引优化&#xff1a;确保查询涉及的列上存在适当的索引&#xff0c;以加快数据检索速度。可以通过使用EXPLAIN语句来查看查询执行计划&#xff0c;并评估是否使用了索引。举例来说&#xff0c;如果…

提升工作效率,用ONLYOFFICE打造高效团队协作环境

作为一名深耕技术领域已有六七年的开发者&#xff0c;同时又是断断续续进行技术创作将近六年的一个小小作者&#xff0c;我在工作和日常生活中&#xff0c;使用过各色各样的软件。 而在最近几年&#xff0c;一款名为ONLYOFFICE的开源办公套件逐渐走进并融入我的工作与生活&…

paraview 处理 fluent 计算结果

paraview 处理 fluent 计算结果 参考链接&#xff1a;https://zhuanlan.zhihu.com/p/598032490 希望先生的主页也很有价值&#xff1a;https://www.cnblogs.com/Xiwang-Sun/p/14943429.html

Edge浏览器的前端开发体验与深度探索

Edge浏览器作为一款备受关注的现代浏览器&#xff0c;在前端开发领域扮演着重要的角色。在这篇博文中&#xff0c;我将分享我对Edge浏览器的使用心得与深度探索&#xff0c;探讨其在前端开发中的优势和特点。 1. Edge浏览器的优势 a. 兼容性 Edge浏览器注重兼容性&#xff0c…

String是最基本的数据类型吗?

在Java编程语言的语境中&#xff0c;探讨“String是否是最基本的数据类型”是一个深入且富有意义的话题。首先&#xff0c;我们需要明确“基本数据类型”的定义&#xff0c;并在此基础上探讨String的特性及其在编程中的角色。 一、基本数据类型的定义 基本数据类型&#xff0…

如何在适用于 Linux 的 Visual Studio Code 中使用 .NET 8 上的 FastReport Avalonia

我们将继续撰写有关在各种操作系统上的 Visual Studio Code 中使用 FastReport Avalonia 的系列文章。在本文中&#xff0c;我们将详细分析如何使用 Visual Studio Code IDE 在 Linux 操作系统上运行 FastReport Avalonia。 Avalonia UI 是一个积极用于开发跨平台用户界面的 .…

Hyper-V 管理器安装的ubutun扩容磁盘空间说明

一、删除检查点 首先把这个想要扩容的虚拟机停止掉&#xff0c;然后找到检查点&#xff0c;全删除掉&#xff0c;否则没法编辑这个虚拟磁盘。 二、编辑虚拟磁盘 下面截图中下一步不能点击的&#xff0c;只要删除检查点之后就可以点击了。点击下一步然后选择扩容&#xff0c;然后…

组合模式(结构型)

目录 一、前言 二、透明组合模式 三、安全组合模式 四、总结 一、前言 组合模式(Composite Pattern)是一种结构型设计模式&#xff0c;将对象组合成树形结构以表示“部分-整体”得层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 组合模式由以下角色组成…