`
ipjmc
  • 浏览: 707478 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Linux线程私有数据

阅读更多

        线程私有数据的使用场景是:某个函数在第一次被调用的时候,分配内存block,在以后每次调用的时候,都是用第一次所分配的内存block,无需再次分配。可以用线程私有数据来存储这个内存block。
        在多线程环境下,如果不使用线程私有数据,由于函数只分配了一个block,所以各个线程在block上必然会有竞争。如果每个线程对这个block的使用是相互独立的,比如对errno的设置,就可以使用线程私有变量来避免竞争。
        可以把线程私有变量看成是一种<key, value>类型的数据结构,对于同一个key,不同的线程可以有不同的value。Linux为这种数据结构提供了GET和SET接口,即:

void *pthread_getspecific(pthread_key_t key);//获取key所对应的线程私有数据
​int pthread_setspecific(pthread_key_t key, const void *value); //设置key所对应的线程私有数据


        一般而言,比如key是全局变量,需要通过pthread_key_create(&key, destructor)初始化key。线程1调用pthread_setspecific(key, value1);设置了key所对应的值value1。这种设置在另外一个线程2是不可见的,即线程2通过pthread_getspecific(key)是获取不到value1的。同样线程2通过pthread_setspecific(key, value2)对线程1也没有任何影响。

        总的来说,就是对于同一个pthread_key,每个线程都对value有一个独立的副本,所以避免了竞争。
        具体例子如下,例子来源于《The Linux Programming Interface - A Linux and UNIX System Programming Handbook》:

#include <stdio.h>
#include <string.h> /* Get declaration of strerror() */
#include <pthread.h>

static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t strerrorKey;
#define MAX_ERROR_LEN 256 /* Maximum length of string in per-thread
                             buffer returned by strerror() */

/* Free thread-specific data buffer */
static void destructor(void *buf) {
    free(buf);
}

/* One-time key creation function */
static void createKey(void) {
    int s;
    /* Allocate a unique thread-specific data key and save the address
       of the destructor for thread-specific data buffers */
    e s = pthread_key_create(&strerrorKey, destructor);
    if (s != 0)
        errExitEN(s, "pthread_key_create");
}

char * strerror(int err) {
    int s;
    char *buf;
    /* Make first caller allocate key for thread-specific data */
    r s = pthread_once(&once, createKey);
    if (s != 0)
        errExitEN(s, "pthread_once");
    t buf = pthread_getspecific(strerrorKey);
    if (buf == NULL) { /* If first call from this thread, allocate
                          buffer for thread, and save its location */
        y buf = malloc(MAX_ERROR_LEN);
        if (buf == NULL)
            errExit("malloc");
        u s = pthread_setspecific(strerrorKey, buf);
        if (s != 0)
            errExitEN(s, "pthread_setspecific");
    }
    if (err < 0 || err >= _sys_nerr || _sys_errlist[err] == NULL) {
        snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", err);
    } else {
        strncpy(buf, _sys_errlist[err], MAX_ERROR_LEN - 1);
        buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */
    }
    return buf;
}


        thread local和线程私有数据在概念上差不多,thread local为线程私有数据提供了更方便的访问接口。
        如下例子

static __thread char local_buf[MAX_ERROR_LEN];


        定义static变量local_buf,通过__thread修饰,则每个线程都对local_buf,都会有一个独立的副本,它们自己不会相互干扰
        通过如下程序的输出,我们可以看到,不同的线程local_buf的地址是不同的,所以每个线程可以独立的对buf修改。


#include <stdio.h>
#include <string.h>
#include <pthread.h>

#define MAX_ERROR_LEN 10240

static char normal_buf[MAX_ERROR_LEN];
static __thread char local_buf[MAX_ERROR_LEN];

void * func(void * arg) {
    printf("thread %x : local_buf %x\n", pthread_self(), local_buf);
    printf("thread %x : normal_buf %x\n", pthread_self(), normal_buf);
}

int main() {

    pthread_t tid;
    pthread_create(&tid, NULL, func, NULL);

    func(NULL);
    pthread_join(tid, NULL);
    return 0;
}
分享到:
评论

相关推荐

    线程私有数据示例代码

    在Linux系统编程中,线程私有数据(Thread Local Storage,TLS)是一种机制,它允许每个线程拥有自己独立的数据副本,确保了数据在多线程环境中的安全性。线程私有数据通常用于存储线程特定的信息,如线程ID、调试...

    linux多线程编程.pdf

    Linux 多线程编程是指在 Linux 操作系统中使用多线程技术来提高程序的执行效率和响应速度。多线程编程可以让程序同时执行多个任务,从而提高程序的整体性能。 线程基础知识 什么是线程?线程(Thread)是操作系统...

    实验二:Linux多线程创建.docx

    Linux 多线程创建实验 本实验的目的是为了进一步掌握在 Linux 系统进行 C 语言编程的方法,进一步了解线程的概念,进一步理解进程与线程的概念,并掌握 C 语言线程创建的方法。 实验原理: 1. Pthread_create ...

    Linux多线程编程_linux_

    在Linux系统中,多线程编程是一种常见的编程模式,它允许多个执行流在同一程序内同时运行,从而提高系统的资源利用率和并发性能。本资料主要针对Linux环境下的多线程编程进行深入探讨。 首先,我们需要了解Linux下...

    Linux系统编程——线程私有数据-附件资源

    Linux系统编程——线程私有数据-附件资源

    linux多线程编程概述.doc

    在Linux系统中,多线程编程是一种常见的编程模式,它允许多个执行流在同一进程中并发运行,从而提高程序的效率和响应性。本篇将深入介绍Linux多线程编程的基本概念、实现方法以及注意事项。 首先,多线程是通过创建...

    linux多线程编程[收集].pdf

    线程包含线程ID、寄存器值、栈、调度优先级和策略、信号屏蔽子、errno变量以及线程私有数据。进程中的所有信息对进程内的所有线程都是共享的,但每个线程有自己的执行上下文。 5. **线程标识**: 每个线程都有一...

    linux多线程编程

    ### Linux多线程编程知识点详解 #### 一、多线程基础 **1.1 定义多线程术语** 多线程编程是指在单个程序中创建多个线程,这些线程可以并发执行,共享相同的内存空间。线程是操作系统能够进行运算调度的最小单位,...

    LINUX线程函数大全.pdf

    线程数据是指线程私有的数据。pthread_key_create 函数用于创建线程数据键,pthread_setspecific 函数用于设置线程数据,pthread_getspecific 函数用于获取线程数据。 LINUX 线程函数大全是一个完善的线程函数手册...

    LINUX系统下多线程与多进程性能分析.pdf

    LINUX系统下多线程与多进程性能分析 本文主要讨论了Linux操作系统下多线程和多进程的性能分析。在Linux系统中,使用多进程处理多个任务,会占用很多系统资源(主要是CPU和内存的使用)。因此,Linux系统对这种弊端...

    嵌入式Linux多线程编程.zip

    在嵌入式Linux系统中,多线程编程是一种常见的优化技术,它允许程序同时执行多个任务,提升系统效率。本文将深入探讨嵌入式Linux环境下如何进行多线程编程,以及C语言源码中的关键概念和技术。 首先,理解多线程的...

    设计Linux多线程编程FAQ.pdf

    Linux多线程编程是现代操作系统中的一个高级话题,涉及到多任务处理,可同时执行多个线程来提高程序的效率和响应速度。在Linux系统中,多线程的实现主要依赖于POSIX线程(pthread),这是一个跨平台的线程API标准,...

    Linux下,多线程通信

    在Linux操作系统中,多线程通信是一个复杂但重要的主题,特别是在网络编程中。本文将深入探讨如何使用pthread库和socket接口来实现多线程网络通信。`pthread_socket`这个文件名暗示了它是实现这一功能的核心代码。 ...

    Pthreads Programming久负盛名的Linux刷线程书籍集合

    《Pthreads Programming》是一本备受推崇的Linux线程编程书籍,它深入浅出地介绍了如何在Linux环境下使用POSIX线程库(Pthreads)进行多线程编程。这本书对于任何致力于提升Linux开发技能,尤其是对并发编程感兴趣的...

    linux unix下多线程与进程

    四、Linux与Unix下的多线程实现 在Linux和Unix系统中,多线程编程主要依赖于POSIX线程库(pthread)。pthread库提供了创建、同步、互斥锁、条件变量等接口,以支持线程的创建和管理。 1. 创建线程:使用`pthread_...

Global site tag (gtag.js) - Google Analytics