多线程 2

本文探讨了多线程编程中的数据共享问题,强调了线程间共享数据可能导致的冲突和挑战。通过介绍关键字`volatile`的使用以及线程特定数据(TSD),阐述了如何管理和保护共享变量。同时提到了线程数据的创建、指定、读取和删除相关函数,以及如何利用`pthread_once`确保键的唯一创建和销毁。
4. 线程的数据处理

  和进程相比,线程的最大优点之一是数据的共享性,各个进程共享父进程处沿袭的数据段,可以方便的获得、修改数据。但这也给多线程编程带来了许多问题。我们必须当心有多个不同的进程访问相同的变量。许多函数是不可重入的,即同时不能运行一个函数的多个拷贝(除非使用不同的数据段)。在函数中声明的静态变量常常带来问题,函数的返回值也会有问题。因为如果返回的是函数内部静态声明的空间的地址,则在一个线程调用该函数得到地址后使用该地址指向的数据时,别的线程可能调用此函数并修改了这一段数据。在进程中共享的变量必须用关键字volatile来定义,这是为了防止编译器在优化时(如gcc中使用-OX参数)改变它们的使用方式。为了保护变量,我们必须使用信号量、互斥等方法来保证我们对变量的正确使用。下面,我们就逐步介绍处理线程数据时的有关知识。


// 线程的共享性为其消耗减负,其中重点是对于变量的操作。

4.1 线程数据

  在单线程的程序里,有两种基本的数据:全局变量和局部变量。但在多线程程序里,还有第三种数据类型:线程数据(TSD: Thread-Specific Data)。它和全局变量很象,在线程内部,各个函数可以象使用全局变量一样调用它,但它对线程外部的其它线程是不可见的。这种数据的必要性是显而易见的。例如我们常见的变量errno,它返回标准的出错信息。它显然不能是一个局部变量,几乎每个函数都应该可以调用它;但它又不能是一个全局变量,否则在A线程里输出的很可能是B线程的出错信息。要实现诸如此类的变量,我们就必须使用线程数据。我们为每个线程数据创建一个键,它和这个键相关联,在各个线程里,都使用这个键来指代线程数据,但在不同的线程里,这个键代表的数据是不同的,在同一个线程里,它代表同样的数据内容。


// 这个键其实就是个vector标记量 猜的。。


和线程数据相关的函数主要有4个:创建一个键;为一个键指定线程数据;从一个键读取线程数据;删除键。
  创建键的函数原型为:

extern int pthread_key_create __P ((pthread_key_t *__key,void (*__destr_function) (void *)));


// 这个double void 究竟啥意思啊

第一个参数为指向一个键值的指针,第二个参数指明了一个destructor函数,如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。这个函数常和函数pthread_once ((pthread_once_t*once_control, void (*initroutine) (void)))一起使用,为了让这个键只被创建一次。函数pthread_once声明一个初始化函数,第一次调用pthread_once时它执行这个函数,以后的调用将被它忽略

// 第二个是destructor  不懂。。这他妈也不像啊沃日。

在下面的例子中,我们创建一个键,并将它和某个数据相关联。我们要定义一个函数createWindow,这个函数定义一个图形窗口(数据类型为Fl_Window *,这是图形界面开发工具FLTK中的数据类型)。由于各个线程都会调用这个函数,所以我们使用线程数据。

复制代码
/* 声明一个键*/
pthread_key_t myWinKey;
/* 函数 createWindow */
void createWindow ( void ) {
    Fl_Window * win;
    static pthread_once_t once= PTHREAD_ONCE_INIT;
    /* 调用函数createMyKey,创建键*/
    pthread_once ( & once, createMyKey) ;
    /*win指向一个新建立的窗口*/
    win=new Fl_Window( 0, 0, 100, 100, "MyWindow");
    /* 对此窗口作一些可能的设置工作,如大小、位置、名称等*/
    setWindow(win);
    /* 将窗口指针值绑定在键myWinKey上*/
    pthread_setpecific ( myWinKey, win);
}

/* 函数 createMyKey,创建一个键,并指定了destructor */
void createMyKey ( void ) {
    pthread_keycreate(&myWinKey, freeWinKey);
}

/* 函数 freeWinKey,释放空间*/
void freeWinKey ( Fl_Window * win){
    delete win;
}
// 瑞了 溜溜球


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值