前面介绍了pthread_create函数,并且当时的例子中,传入的参数都是空指针,而不是指向pthread_attr_t结构的指针。可以使用pthread_attr_t结构修改线程默认属性,并把这些属性与创建的线程联系起来。可以使用pthread_attr_init函数初始化pthread_attr_t结构。调用pthread_attr_init以后,pthread_attr_t结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。如果要修改其中个别属性的值,需要调用其他的函数。

#include <pthread.h>

int pthread_attr_init( pthread_attr_t *attr );

int pthread_attr_destroy( pthtread_attr_t *attr );

两个函数的返回值都是:若成功则返回0,否则返回错误编号

如果要去除对pthread_attr_t结构的初始化,可以调用pthread_attr_destroy函数。如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy将会释放该内存空间。除此之外,pthread_attr_destroy还会用无效的值初始化属性对象,因此如果该属性对象被误用,将会导致pthread_create函数返回错误。

pthread_attr_t结构对应用程序是透明的,也就是说应用程序并不需要了解有关属性对象内部结构的任何细节,因而可以增强应用程序的可移植性。POSIX.1沿用了这种模型,并且为查询和设置每种属性定义了独立的函数

名称

  描述

detachstate

线程的分离状态属性

guardsize

线程栈末尾的警戒缓冲区大小(字节数)

stackaddr

线程栈的最低地址

stacksize

线程栈的大小(字节数)

如果对现有的某个线程的终止状态不感兴趣的话,可以使用pthread_detach函数让操作系统在线程退出时收回它所占用的资源。

如果在创建线程时就知道不需要了解线程的终止状态,则可以修改pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。可以使用pthread_attr_setdetachstate函数把线程属性detachstate设置为下面的两个合法值之一:设置为PTHREAD_CREATE_DETACHED,以分离状态启动线程;或者设置为PTHREAD_CREATE_JOINABLE,正常启动线程,应用程序可以获取线程的终止状态。

#include <pthread.h>
 
int pthread_attr_getdetachstate( const pthread_attr_t *restrict attr,
                                 int *detachstate );
 
int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate );
 
两者的返回值都是:若成功则返回0,否则返回错误编号
 
可以调用pthread_attr_getdetachstate函数获取当前的detachstate线程属性,第二个参数所指向的整数用来保存获取到的detachstate属性值:PTHREAD_CREATE_DETACHED,或PTHREAD_CREATE_JOINABLE)。
 
实例
 
程序:以分离状态创建的线程
 
复制代码
#include "apue.h"
#include <pthread.h>
 
int
makethread(void *(*fn)(void *), void *arg)
{
    int            err;
    pthread_t       tid;
    pthread_attr_t    attr;
 
    err = pthread_attr_init(&attr);
    if(err != 0)
        return(err);
    err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if(err == 0)
        err = pthread_create(&tid, &attr, fn, arg);
    pthread_attr_destroy(&attr);
    return(err);
}
 
这里忽略了pthread_attr_destroy函数调用的返回值。在这种情况下,由于对线程属性进行了合理的初始化,pthread_attr_destroy一般不会失败。但是如果pthread_attr_destroy确实出现了失败的情况,清理工作就会变得很困难:必须销毁刚刚创建的线程,而这个线程可能已经运行,并且与pthread_attr_destroy函数可能是异步执行的。忽略pthread_attr_destroy的错误返回可能出现的最坏的情况是:如果pthread_attr_init分配了内存空间,这些内存空间会被泄露。另一方面,如果pthread_attr_init成功地对线程属性进行了初始化,但pthread_attr_destroy在做清理工作时却出现了失败,就没有任何补救策略,因为线程属性结构对应用程序来说是透明的,可以对线程属性结构进行清理的唯一接口是pthread_attr_destroy,但它失败了。
 
对于遵循POSIX标准的操作系统来说,并不一定要支持线程栈属性,但是对于遵循XSI的系统,支持线程栈属性就是必须的。可以在编译阶段使用_POSIX_THREAD_ATTR_STACKADDR和_POSIX_ATTR_STACKSIZE符号来检查系统是否支持线程栈属性,如果系统定义了这些符号,就说明它支持相应的线程栈属性。也可以通过在运行阶段把_SC_THREAD_ATTR_STACKADDR和_SC_THREAD_ATTR_STACKSIZE参数传给sysconf函数,检查系统对线程栈属性的支持情况。
 
POSIX.1定义了线程栈属性的一些操作接口。线程栈属性的查询和修改一般是通过较新的函数pthread_attr_getstack和pthread_attr_setstack来进行。
 
 
#include <pthread.h>
 
int pthread_attr_getstack( const pthread_attr_t *restrict attr,
                       void **restrict stackaddr,
                       size_t *restrict stacksize );
 
int pthread_attr_setstack( const pthread_attr_t *attr,
                           void *stackaddr, size_t *stacksize );
 
两者的返回值都是:若成功则返回0,否则返回错误编号
 
 
如果希望改变栈的默认大小,但又不想自己处理线程栈的分配问题,这时使用pthread_attr_setstacksize函数就非常有用。
 
线程属性guardsize控制着线程栈末尾之后用以避免栈溢出的扩展内存的大小。这个属性默认设置为PAGESIZE个字节。可以把guardsize线程属性设为0,从而不允许属性的这种特征行为发生:在这种情况下不会提供警戒缓冲区。同样地,如果对线程属性stackaddr作了修改,系统就会假设我们会自己管理栈,并使警戒栈缓冲区机制无效,等同于把guardsize属性设为0。
 
复制代码
#include <pthread.h>
 
int pthread_attr_getguardsize( const pthread_attr_t *restrict attr, 
                        size_t *restrict guardsize );
 
int pthread_attr_setguardsize( pthread_attr_t *attr, size_t guardsize );
 
两者的返回值都是:若成功则返回0,否则返回错误编号
 
 
如果guardsize线程属性被修改了,操作系统可能把它取为页大小的整数倍。如果线程的栈指针溢出到警戒区域,应用程序就可能通过信号接收到出错信息。

Linux c编程:线程属性的更多相关文章

  1. Linux系统编程 —线程属性

    在之前的章节中,我们在调用pthread_create函数创建线程时,第二个参数(即线程属性)都是设为NULL,即使用默认属性.一般情况下,使用默认属性已经可以解决我们开发过程中的大多数问题. 但是, ...

  2. LInux多线程编程----线程属性pthread_attr_t

    1.每个POSIX线程有一个相连的属性对象来表示属性.线程属性对象的类型是pthread_attr_t,pthread_attr_t 在文件/usr/include/bits/pthreadtypes ...

  3. UNIX环境高级编程——线程属性

    pthread_attr_t 的缺省属性值 属性 值 结果 scope PTHREAD_SCOPE_PROCESS 新线程与进程中的其他线程发生竞争. detachstate PTHREAD_CREA ...

  4. Linux多任务编程——线程

    线程基础 △ 由于进程的地址空间是私有的,因此在进行上下文切换时,系统开销比较大 △ 在同一个进程中创建的线程共享该进程的地址空间 △ 通常线程值得是共享相同地址空间的多个任务 △ 每个线程的私有这些 ...

  5. Linux多线程编程——线程的创建与退出

    POSIX线程标准:该标准定义了创建和操纵线程的一整套API.在类Unix操作系统(Unix.Linux.Mac OS X等)中,都使用Pthreads作为操作系统的线程.Windows操作系统也有其 ...

  6. Linux的POSIX线程属性

    创建POSIX线程的函数为 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routin ...

  7. linux系统编程--线程

    安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...

  8. Linux 多线程编程--线程退出

    今天分析项目中进程中虚存一直增长问题,运行10个小时虚存涨到121G ,RSS占用为16G 非常恐怖. Valgrind测试无内存泄漏. 内存32G 64bit系统信息如下: Linux线程使用方式是 ...

  9. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...

  10. linux系统编程--线程同步

    同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需 ...

随机推荐

  1. 倍福TwinCAT(贝福Beckhoff)基础教程4.2 TwinCAT如何读写CSV文件

    本程序只是在官方范例程序上稍作修改,在官方原有的范例中,演示了多种模式的读写(可以认为CSV文件是比TXT文件需要更多数据量的时候使用,比如记录一个小型的数据库集合)   但是写的比较混乱,甚至没有H ...

  2. 【VBA】查看当前窗口的宽与高

    打开的Excle如何使用VBA查看当前窗口的宽与高呢?代码如下: Sub 查看宽度与高度() Dim myWidth As Double Dim myHeigth As Double myWidth ...

  3. Flex 自定义打印控件编写

    打印历来是web应用一个比较棘手的问题,幸好flex web应用是运行在flash player上的,flash player可以访问打印机,所以flex 应用可以实现比较强大的打印功能.Flex 自 ...

  4. Oracle 日期总结

    一.带星期格式 .SELECT to_char(to_date('2014-12-12','yyyy-mm-dd'),'MM-DD (DAY)') FROM DUAL .SELECT to_char( ...

  5. 打造Android万能上拉下拉刷新框架--XRefreshView(三)

    转载请注明出处:http://blog.csdn.net/footballclub/ 打造Android万能上拉下拉刷新框架–XRefreshView(一) 打造Android万能上拉下拉刷新框架–X ...

  6. The Application does not have a valid signature

    真机运行程序,报错(The application does not have a valid signature,如图 环境:Xcode7.3,使用cocoapods管理第三方库 如果确认证书没有问 ...

  7. Java GUI编程SwingUtilities.invokeLater作用

    1 http://blog.micxp.com/index.php/archives/109/ 2

  8. nginx 做前端代理时proxy参数配置

    1.后台可登录: proxy_connect_timeout 300s; proxy_send_timeout ; proxy_read_timeout ; proxy_buffer_size 256 ...

  9. Hibernate二次学习一----------Hibernate简单搭建

    因为博客园自带的markdown不太好用,因此所有markdown笔记都使用cmd_markdown发布 Hibernate二次学习一----------Hibernate简单搭建: https:// ...

  10. rm 命令简要

    rm   单独使用只能删除文件不能删除文件夹    rm -r 可以删除文件夹和文件 1.rm   test.txt   删除文件 2.rm   -r   test.txt   每次删除的时候都询问是 ...