线程特定的存储器

来源:互联网 发布:太原网站搜索引擎优化 编辑:程序博客网 时间:2024/06/05 07:39

线程特定的存储器设计模式允许多线程使用一个“逻辑上全局的访问点”获取一个局限于某一个线程的对象,而不会导致对象访问中的加锁开销。

例如,多线程访问全局errno变量,会导致加锁同步开销。

解决方案:为每个具体线程的对象引入一个全局访问点,但是在每个线程的存储器中保存“真实”的对象。应用程序仅通过它们的全局访问点管理这些线程特定对象。
该模式有六个参与者组成。
1.线程特定对象是一个只能有特定线程访问的对象实例。
2.关键字工厂分配关键字来标识一个线程特定对象。
3.线程特定对象集包含与特定线程关联的线程特定对象的集合。
4.线程特定对象代理,使客户机像访问普通对象一样访问一个特定类型的线程特定对象。
5.应用程序线程。

类图:
这里写图片描述

时序图
这里写图片描述
这里写图片描述

代码示例:

#include <pthread.h>#include <stdlib.h>#include <stdint.h>#include <stdio.h>pthread_key_t errno_location;pthread_once_t errno_init;void destruct_errno(void* ptr){    free(ptr);}void init_errno(void){    pthread_key_create(&errno_location, destruct_errno);}int32_t* get_errno_location(void){    void* ptr;    (void)pthread_once(&errno_init, init_errno);    ptr = pthread_getspecific(errno_location);    if (!ptr)    {        ptr = calloc(1, sizeof(int32_t));        pthread_setspecific(errno_location, ptr);    }    return (int32_t*)ptr;}void* thread_function (void* args){  int32_t *erro =   (int32_t*)get_errno_location();  printf("erro:%d\n",*erro);  *erro = pthread_self();  int* perro =get_errno_location();  printf("pthread_self:%d, erro:%d\n",pthread_self(), *perro);}int main () {  int i = 0;  pthread_t threads[5];  for (i = 0; i < 5; ++i)  {      pthread_create (&(threads[i]), NULL, thread_function, NULL);  }  for (i = 0; i < 5; ++i)  {      pthread_join (threads[i], NULL);  }  return 0;}

运行结果:
这里写图片描述

该模式优点:
1.高效。去除加速解锁的开销。
2.可重用行。线程特定存储器模式代码可以与具体的应用程序类相分离,可以使开发者避免考虑复杂并且不可移植的线程相关逻辑。
3.易用性。理解简单,结构清晰,方便使用。
4.可移植性。

缺点:
1.它鼓励对(线程特定的)全局对象的使用。
2.它使系统结构变得模糊。
3.它限制了实现方式的选择。不是所有语言都支持参数类型和只能指针,并非所有的应用程序都提供扩展接口。

0 0
原创粉丝点击