今天面试那哥们问起线程属性,me竟然就说出了一个,囧
学习:http://blog.csdn.net/zsf8701/article/details/7842392
http://blog.csdn.net/jxhnuaa/article/details/3254299
http://blog.sina.com.cn/s/blog_9bd573450101hgdr.html
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
在线程建立时,第二参数是设置线程的属性,当为NULL时,设置成系统默认属性:非邦定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。
/usr/include/pthread.h 包含 bits/pthreadtypes.h union pthread_attr_t { char __size[__SIZEOF_PTHREAD_ATTR_T]; long int __align; }; typedef union pthread_attr_t pthread_attr_t; typedef struct { int detachstate; 线程的分离状态 int schedpolicy; 线程调度策略 struct sched_param schedparam; 线程的调度参数 int inheritsched; 线程的继承性 int scope; 线程的作用域 size_t guardsize; 线程栈末尾的警戒缓冲区大小 int stackaddr_set; void * stackaddr; 线程栈的位置 size_t stacksize; 线程栈的大小 }pthread_attr_t;
从上面的结构可以看到线程都有些什么属性,下面一些函数来设置线程属性:
#include <pthread.h> int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr);
功能:initialize and destroy thread attributes object.
Calling pthread_attr_init() on a thread attributes object that has already been initialized results in undefined behavior.
When a thread attributes object is no longer required, it should be destroyed using the pthread_attr_destroy() function. Destroying a thread attributes
object has no effect on threads that were created using that object.
On success, these functions return 0; on error, they return a nonzero error number.
#include <pthread.h> int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
功能:set/get detach state attribute in thread attributes object.
线程的分离状态决定一个线程以什么样的方式来终止自己
PTHREAD_CREATE_DETACHED
分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。应该根据自己的需要,选择适当的分离状态
PTHREAD _CREATE_JOINABLE
线程的默认属性是非分离状态,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。
如果设置一个线程为分离线程,而这个线程运行又非常快,它很可能在pthread_create函数返回之前就终止了,它终止以后就可能将线程号和系统资源移交给其他的线程使用,这样调用pthread_create的线程就得到了错误的线程号。要避免这种情况可以采取一定的同步措施,最简单的方法之一是可以在被创建的线程里调用pthread_cond_timewait函数,让这个线程等待一会儿,留出足够的时间让函数pthread_create返回。设置一段等待时间,是在多线程编程里常用的方法。但是注意不要使用诸如wait()之类的函数,它们是使整个进程睡眠,并不能解决线程同步的问题。
#include <pthread.h> int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
功能:set/get scheduling policy attribute in thread attributes object
POSIX标准指定了三种调度策略:先入先出策略 (SCHED_FIFO)、循环策略 (SCHED_RR) 和自定义策略 (SCHED_OTHER)。SCHED_FIFO 是基于队列的调度程序,对于每个优先级都会使用不同的队列。SCHED_RR 与 FIFO 相似,不同的是前者的每个线程都有一个执行时间配额。SCHED_FIFO 和 SCHED_RR 是对 POSIX Realtime 的扩展。SCHED_OTHER 是缺省的调度策略。
新线程默认使用 SCHED_OTHER 调度策略。线程一旦开始运行,直到被抢占或者直到线程阻塞或停止为止。
SCHED_FIFO
如果调用进程具有有效的用户 ID 0,则争用范围为系统 (PTHREAD_SCOPE_SYSTEM) 的先入先出线程属于实时 (RT) 调度类。如果这些线程未被优先级更高的线程抢占,则会继续处理该线程,直到该线程放弃或阻塞为止。对于具有进程争用范围 (PTHREAD_SCOPE_PROCESS)) 的线程或其调用进程没有有效用户 ID 0 的线程,请使用 SCHED_FIFO,SCHED_FIFO 基于 TS 调度类。
SCHED_RR
如果调用进程具有有效的用户 ID 0,则争用范围为系统 (PTHREAD_SCOPE_SYSTEM)) 的循环线程属于实时 (RT) 调度类。如果这些线程未被优先级更高的线程抢占,并且这些线程没有放弃或阻塞,则在系统确定的时间段内将一直执行这些线程。对于具有进程争用范围 (PTHREAD_SCOPE_PROCESS) 的线程,请使用 SCHED_RR(基于 TS 调度类)。此外,这些线程的调用进程没有有效的用户 ID 0。
#include <pthread.h> int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);
功能:set/get scheduling parameter attributes in thread attributes object
struct sched_param { int sched_priority; /* Scheduling priority */ };
#include <pthread.h> int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
功能:set/get inherit scheduler attribute in thread attributes object
PTHREAD_EXPLICIT_SCHED
PTHREAD_INHERIT_SCHED
前者表示使用结构pthread_attr_t指定的调度算法,后者表示继承父线程使用的调度算法,默认为前者
#include <pthread.h> int pthread_attr_setscope(pthread_attr_t *attr, int scope); int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
功能:设置线程作用域
PTHREAD_SCOPE_SYSTEM
PTHREAD_SCOPE_PROCESS
前者表示在整个系统内竞争CPU资源,后者表示在同一进程内竞争CPU资源,默认为前者
#include <pthread.h> int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
功能: set/get guard size attribute in thread attributes object
在线程栈顶留出一段空间,防止栈溢出。
当栈指针进入这段保护区时,系统会发出错误,通常是发送信号给线程。
该属性默认值是PAGESIZE大小,该属性被设置时,系统会自动将该属性大小补齐为页大小的整数倍。
当改变栈地址属性时,栈保护区大小通常清零。
#include <pthread.h> int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
功能:获取/设置线程栈及其大小
stackaddr should point to the lowest addressable byte of a buffer of stacksize bytes that was allocated by the caller. The pages of the allocated buffer should be both readable and writable.
#include <pthread.h> int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr); int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr); #include <pthread.h> int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
实例见:man pthread_attr_init
线程属性总结