专栏首页owentAndroid和IOS的TLS问题

Android和IOS的TLS问题

这个问题起源于以前给客户端写的一个log模块,然后里面为了线程安全且多线程下不互相写乱,并且因为这些系统基本都用比较高版本的编译器,都支持C++11了,所以就用了C++11的TLS功能。

但是Android的默认std库并不是libstdc++或者libc++,而是Bionic。IOS不知道是什么版本的标准库都不支持thread_local的关键字。 这个之前写过一个记录提到过 Android NDK undefined reference to ___tls_get_addr 错误。如果使用这个关键字,链接的时候会报错说找不到符号。

当时梅花太多时间,而是在这两个环境下直接用了加锁的方式。但是我们开发在Windows上,实际发布产品的时候是在Android和IOS上,这么做也就意味着开发时性能高过发布的代码。这显然不够美好,所以这两天做底层优化就顺带解决了一下。

解决方法也很简单,这两种系统虽然不支持C++11的TLS关键字,但是它们支持pthread规范啊。那么就可以这种情况直接用pthread来处理。(如果以后需要适配Windows Phone系统,并且又不支持的话再想其他办法吧)。 简化的代码如下:

#if defined(THREAD_TLS_ENABLED) && 1 == THREAD_TLS_ENABLED
namespace util {
    namespace log {
        namespace detail {
            char *get_log_tls_buffer() {
                static THREAD_TLS char ret[LOG_WRAPPER_MAX_SIZE_PER_LINE];
                return ret;
            }
        }
    }
}
#else

#include <pthread.h>
namespace util {
    namespace log {
        namespace detail {
            static pthread_once_t gt_get_log_tls_once = PTHREAD_ONCE_INIT;
            static pthread_key_t gt_get_log_tls_key;

            static void dtor_pthread_get_log_tls(void *p) {
                char *buffer_block = reinterpret_cast<char *>(p);
                if (NULL != buffer_block) {
                    delete[] buffer_block;
                }
            }

            static void init_pthread_get_log_tls() { (void)pthread_key_create(&gt_get_log_tls_key, dtor_pthread_get_log_tls); }

            char *get_log_tls_buffer() {
                (void)pthread_once(&gt_get_log_tls_once, init_pthread_get_log_tls);
                char *buffer_block = reinterpret_cast<char *>(pthread_getspecific(gt_get_log_tls_key));
                if (NULL == buffer_block) {
                    buffer_block = new char[LOG_WRAPPER_MAX_SIZE_PER_LINE];
                    pthread_setspecific(gt_get_log_tls_key, buffer_block);
                }
                return buffer_block;
            }
        }
    }
}

#endif

// 然后后面需要用缓冲区的时候用get_log_tls_buffer()函数获取

完整代码见: https://github.com/atframework/atframe_utils/blob/master/src/log/log_wrapper.cpp

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • LLVM+Clang+Libcxx+Libcxxabi(3.6)工具链编译(完成自举编译)

    LLVM和Clang工具链的生成配置文件写得比较搓,所以略微麻烦,另外这个脚本没有经过多环境测试,不保证在其他Linux发行版里正常使用。

    owent
  • 非常帅气的Linq to sql

    Linq是.NET 3里新增的东西,我在软件工程课程设计里初步应用到一点,而且主要用在Lambda表达式上,今天算是在好奇心驱动下尝试了一下在数据库方面的应用。

    owent
  • 重写了llvm+clang+libc++和libc++abi的构建脚本

    由于之前整理的服务器框架已经完成了,就需要用各种静态分析工具跑一遍。原来的llvm+clang的编译脚本是从GCC那个脚本copy过来然后改的,使用的时候各种问...

    owent
  • Python|木兰编程语言详解

    打开软件。出现下面的交互界面。由于对ulang语言一窍不通,只能使用help命令。

    Rare0716
  • 3.1 .1、Google Tag Manager基础知识——GTM简介

    Google Tag Manager(谷歌代码管理系统,GTM)可以帮助您快速轻松地更新网站或移动应用上的代码和代码段,例如用于流量分析和营销优化的代码和代码段...

    GA小站
  • Zookeeper的日志配置

    zookeeper使用广泛,作为接近于开箱即用的一个服务,其日志的配置貌似没有作得很方便,接下来我们总结下这个日志配置的方法

    扫帚的影子
  • SIGIR2020|图灵奖得主Hinton主题演讲:无监督对比学习将是神经网络的未来

    第二种方法,是Becker和Hinton在1992年提出的,通过训练一个深层神经网络的两个副本,以相同图像的两种不同剪裁作为输入,产生具有高度互信息的输出向量。...

    新智元
  • 简书上实现代码块的几种方式

    简书目前还没有插入代码块的选项,对it这一行的我们来说,为了给大家分享技术,代码片呈现的方式或多或少很有必要啦~~,下面,总结一下我知道的几种Markdown模...

    wblearn
  • FastTree:速度最快的最大似然法进化树构建软件

    FastTree 是基于最大似然法构建进化树的软件,它最大的特点就是运行速度快,支持几百万条序列的建树任务。官方的说法是,对于大的比对数据集,FastTree ...

    生信修炼手册
  • 【ICCV2017 Tutorial】何恺明博士最佳论文Mask R-CNN Tutorial 报告(附下载)

    【导读】当地时间 10月 22 日到10月29日,两年一度的计算机视觉国际顶级会议 International Conference on Computer V...

    WZEARW

扫码关注云+社区

领取腾讯云代金券