线程中特有的线程存储, Thread Specific Data 。线程存储有什么用了?他是什么意思了?
大家都知道,在多线程程序中,所有线程共享程序中的变量。现在有一全局变量,所有线程都可以使用它,改变它的值。而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。
函数原型:
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 创建
 int pthread_setspecific(pthread_key_t key, const void *value); 赋值
void *pthread_getspecific(pthread_key_t key); 取值
下面说一下线程存储的具体用法。
l 创建一个类型为 pthread_key_t 类型的变量。
调用 pthread_key_create() 来创建该变量。该函数有两个参数,第一个参数就是上面声明的 pthread_key_t 变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数指针可以设成 NULL ,这样系统将调用默认的清理函数。
当线程中需要存储特殊值的时候,可以调用 pthread_setspcific() 。该函数有两个参数,第一个为前面声明的 pthread_key_t 变量,第二个为 void* 变量,这样你可以存储任何类型的值。
如果需要取出所存储的值,调用 pthread_getspecific() 。该函数的参数为前面提到的 pthread_key_t 变量,该函数返回 void * 类型的值。 下面是一个如何使用线程存储的例子: #include <malloc.h>
#include <pthread.h>
#include <stdio.h>
/* The key used to associate a log file pointer with each thread. */
static pthread_key_t thread_log_key;
/* Write MESSAGE to the log file for the current thread. */
void write_to_thread_log (const char* message) {
  FILE* thread_log = (FILE*) pthread_getspecific (thread_log_key);
  fprintf (thread_log, “%s\n”, message);
}
/* Close the log file pointer THREAD_LOG. */
void close_thread_log (void* thread_log) {
  fclose ((FILE*) thread_log);
}
void* thread_function (void* args) {
  char  thread_log_filename[];
  FILE* thread_log;
  /* Generate the filename for this thread’s log file. */
  sprintf (thread_log_filename, “thread%d.log”, (int) pthread_self ()); /* Open the log file. */
  thread_log = fopen (thread_log_filename, “w”);
  /* Store the file pointer in thread-specific data under thread_log_key. */
  pthread_setspecific (thread_log_key, thread_log);
  write_to_thread_log (“Thread starting.”);
  /* Do work here... */
  return NULL;
}
int main () {
  int i;
  pthread_t threads[];
  /* Create a key to associate thread log file pointers in thread-specific data. Use close_thread_log to clean up the file pointers.   */
  pthread_key_create (&thread_log_key, close_thread_log); /* Create threads to do the work. */   for (i = ; i < ; ++i)
    pthread_create (&(threads[i]), NULL, thread_function, NULL); /* Wait for all threads to finish. */
  for (i = ; i < ; ++i)
    pthread_join (threads[i], NULL); return ;
}
最后说一下线程的本质。
其实在Linux 中,新建的线程并不是在原先的进程中,而是系统通过一个系统调用clone() 。该系统copy 了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。不过这个copy 过程和fork 不一样。copy 后的进程和原先的进程共享了所有的变量,运行环境。这样,原先进程中的变量变动在copy 后的进程中便能体现出来。

线程存储(Thread Specific Data)的更多相关文章

  1. 41、Thead线程 System.Thread与互斥体Mutex

    Thead线程 System.Thread 使用Thread类可以创建和控制线程.下面的代码是创建和启动一个新线程的简单例子.Thread 类的构造函数重载为接受ThreadStart和Paramet ...

  2. 线程(Thread,ThreadPool)、Task、Parallel

    线程(Thread.ThreadPool) 线程的定义我想大家都有所了解,这里我就不再复述了.我这里主要介绍.NET Framework中的线程(Thread.ThreadPool). .NET Fr ...

  3. 从零开始构建一个Reactor模式的网络库(二)线程类Thread

    线程类Thread是对POSIX线程的封装类,因为要构建的是一个Linux环境下的多线程网络库,对线程的封装是很必要的. 首先是CurrentThread命名空间,主要是获取以及缓存线程id: #if ...

  4. java并发编程学习: 守护线程(Daemon Thread)

    在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...

  5. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  6. 【转】线程、Thread类和线程终止

    一.线程Thread启动 0. Thread类实现了java.lang.Runnable接口,即实现了run方法.虽然在Sun JDK中,start()调用了start0()方法,start0()方法 ...

  7. java学习笔记之线程(Thread)

    刚开始接触java多线程的时候,我觉得,应该像其他章节的内容一样,了解了生命周期.构造方法.方法.属性.使用的条件,就可以结束了,然而随着我的深入学习了解,我发现java的多线程是java的一个特别重 ...

  8. 7种创建线程方式,你知道几种?线程系列Thread(一)

    前言 最近特别忙,博客就此荒芜,博主秉着哪里不熟悉就开始学习哪里的精神一直在分享着,有着扎实的基础才能写出茁壮的代码,有可能实现的逻辑有多种,但是心中必须有要有底哪个更适合,用着更好,否则则说明我们对 ...

  9. 从源码解读线程(Thread)和线程池(ThreadPoolExecutor)的状态

    线程是比进程更加轻量级的调度执行单位,理解线程是理解并发编程的不可或缺的一部分:而生产过程中不可能永远使用裸线程,需要线程池技术,线程池是管理和调度线程的资源池.因为前不久遇到了一个关于线程状态的问题 ...

随机推荐

  1. CSS3 animation-iteration-count:infinite

    原文:http://www.w3chtml.com/css3/properties/animation/animation-iteration-count.html animation-iterati ...

  2. C++中引用编译过的C代码为什么要用“extern c”

    函数经过编译系统的翻译成汇编,函数名对应着汇编标号.  因为C编译函数名与得到的汇编代号基本一样,如:fun()=>_fun, main=>_main  但是C++中函数名与得到的汇编代号 ...

  3. C# XMLHttpRequest对象—Ajax实例

    Get: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...

  4. Understanding When to use RabbitMQ or Apache Kafka

    https://content.pivotal.io/rabbitmq/understanding-when-to-use-rabbitmq-or-apache-kafka How do humans ...

  5. yuv转opencv中的IplImage

    http://www.2cto.com/kf/201208/145559.html http://www.opencv.org.cn/forum.php?mod=viewthread&tid= ...

  6. MACHINE_START-内核板级初始化实现机制(linux3.1.0)

    转:https://blog.csdn.net/charliewangg12/article/details/41518549 在驱动开发时,我们都是以一块开发板为基础移植驱动程序.每一块开发板对应一 ...

  7. [GUI] Linux中的图形管理

    转:http://www.cnblogs.com/yongpenghan/p/4555619.html 做了一段时间linux下与QT事件相关的工作,经常会遇到X11,总是苦于无法完全理解其与linu ...

  8. 黑色CSS3立体动画菜单

    在线演示 本地下载

  9. CSS3动画表单

    在线演示 本地下载

  10. OC_id类型

     博客正式开通啦!以后会每天为大家更新知识,将过去学习的笔记发布出来.供大家学习交流. 在Objective-C 中,id 类型是一个独特的数据类型.在概念上,类似Java 的Object 类,可以转 ...