您的位置:首页 > 其它

线程特定的存储器

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

例如,多线程访问全局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.它限制了实现方式的选择。不是所有语言都支持参数类型和只能指针,并非所有的应用程序都提供扩展接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息