当前位置:网站首页>eventfd和__thread的应用
eventfd和__thread的应用
2022-08-06 13:00:00 【刚入门的代码spa技师】
eventfd和__thread的应用
muduo可以通过设置线程数量来决定开几个EventLoop,一个EventLoop有多个channel。当channel上有事件发生时,就应该在他所属的EventLoop上执行。
比如在一个mainReactor一个subReactor的情况下,mainReactor监听到一个新连接,要把这个新连接派发给subReactor。而subReactor可能大部分的时间都在loop(epoll_wait)阻塞的状态,mainReactor不能强把这个新连接塞给subReactor的Poller,这不合理也不安全,这就需要唤醒阻塞的subReactor,并且让它自己来把这个新连接添加到它的Poller上。
如何确定这个新连接是在它所属的EventLoop上处理的呢?
one loop per thread,我们可以通过系统中唯一的线程ID来确认他们所属的loop。
eventfd唤醒subReactor

eventfd用于创建一个专门唤醒事件的一个文件描述符。
当有新连接到来时,如果subReactor还在阻塞,不能一直等到subReactor阻塞返回,应该把它唤醒,立刻处理新连接。
我们可以让subReactor监听一个eventfd,在需要唤醒时往eventfd里写一个自己,这样苏北Reactor就可以从loop(epoll_wait)阻塞状态返回了。
用传统的pipe也可以实现,但eventfd可以更高效的唤醒,因为他不必管理缓冲区。
巧用__thread关键字
__thread是GCC内置的线程局部存储设施(thread local storage)。可以用来修饰POD类型,不能修饰class类型,因为无法自动调用构造和析构函数。
__thread可以用于修饰全局变量、函数内的静态变量,但是不能用于修饰函数的局部变量会在class的普通成员变量。另外,__thread变量的初始化只能用编译期常量。例如:
__thread string t_obj1("hello"); //错误,不能调用对象的构造函数
__thread string* t_obj2 = new string; //错误,初始化必须用编译器常量
__thread string* t_obj3 = NULL; //正确,但是需要手工初始化并销毁对象
__thread修饰的变量每个线程都有一份独立实体,各个线程的变量值互不干扰。
获取当前线程id接口:
CurrentThread.h
#pragma once
#include <unistd.h>
#include <sys/syscall.h>
namespace CurrentThread
{
extern __thread int t_cachedTid;
void cacheTid();
inline int tid()
{
if(__builtin_expect(t_cachedTid == 0, 0))
{
cacheTid();
}
return t_cachedTid;
}
}
CurrentThread.cc
#include "CurrentThread.h"
namespace CurrentThread
{
__thread int t_cachedTid = 0;
void cacheTid()
{
if(t_cachedTid == 0)
{
//通过Linux系统调用,获取当前线程的pid值
t_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid));
}
}
}
因为每个线程都有__thread修饰变量的一份独立实体,在线程调用CurrentThread::tid,获取的一定是当前线程的id。
边栏推荐
- How to recover EOS keys after being stolen?
- 【SSL集训DAY1】C【暴力】【数学】
- Security on the sixth day practice after class
- OpenFeign【与Feign关系 OpenFeign详解】
- Extension and customization of Istio
- Learned Valley Learning Records] Super summary, share with heart | Basic usage of mongodb
- 干货 | 那些鬼斧神工的池化操作,看完我炸裂!
- leetcode.10 Regular Expressions
- 解决创建虚拟机时No DEFAULT or UI configuration directive found问题
- LeetCode 896. 单调数列
猜你喜欢

链表 | 找出并返回链表相交的起始节点 | leecode刷题笔记

Ansible自动化运维、ZABBIX监控

Kubernetes日常故障解决

【SSL集训DAY1】C【暴力】【数学】
![[极客大挑战 2019]PHP 1](/img/86/a65393768cd9cf129132fcd374dcd2.png)
[极客大挑战 2019]PHP 1

链表 | 两两交换链表中的节点 | leecode刷题笔记

The "Pytorch Common Functions Manual" compiled by Dr. Harbin Institute of Technology for half a year is open for download!Contains more than 200 functions! …

Web page side IM products RainbowChat - Web v4.1 version has been released

40度高温,如何通过SOLIDWORKS找到室内最凉快的地方?

【TypeScript】深入学习TypeScript装饰器
随机推荐
EOS密钥被盗后如何恢复?
Luogu P1776: Treasure Screening ← Multiple Knapsack Problem Binary Optimization
PHP fopen write file content
MD5【加密以及解密】
Nacos启动失败:Nacos Server did not start because dumpservice bean construction failure:No DataSource set
SQL 注入复习总结
锐捷MPLS 网络配置实例 ---尚文网络奎哥
AlexNet—论文分析及复现
易知微数字孪生智慧港口|打造智能化调度综合管控“大脑”,实现港口建设“新升级”
分布式锁的应用实践 | 微服务申请逐渐递增且不重复的号码
Shardingsphere 强制主库查询
OpenFeign【与Feign关系 OpenFeign详解】
NAS 硬件采购配置记录
多重背包问题 ← 规模小时可转化为0-1背包问题
One article to understand what is kubernetes Service
vulnhub-DC-2 drone penetration record
动手学深度学习_ResNet
SQL图解面试题:如何实现精细化运营?(具体且精确的全过程详细讲解)
Kotlin-inline:你需要知道的一切(Android)
Istio的扩展和定制