1、线程限制
Single Unix定义了一线线程操作的限制,和其他的限制一样,可以通过sysconf来查询。和其它的限制使用目的一样,这些限制的使用是为了应用程序的在不同操作系统实现之间的可移植性。 一些限制:
2、线程属性
在调用pthread_create函数创建一个新线程时候可以指定线程的属性,属性类型为pthread_attr_t,该结构对应用程序是不透明,操作函数如下:
int pthread_attr_init(pthread_attr_t *attr); //初始化线程属性 int pthread_attr_destroy(pthread_attr_t *attr); //释放线程属性空间
线程属性主要有:
3、同步属性(晕了)
(1)互斥量属性:有进程共享属性、健壮属性以及类型属性三种。
进程共享属性是可选的,互斥量属性数据类型为pthread_mutexattr_t。在进程中,多个线程可以访问同一个同步对象,默认情况进程共享互斥量属性为:PTHREAD_PROCESS_PRIVATE。
互斥量健壮属性与在多个进程间共享的互斥量有关。这意味着,当持有互斥量的进程终止时,需要解决互斥量状态恢复的问题。这种情况发生时,互斥量处于锁定状态,恢复起来很困难。其他阻塞在这个锁的进程将会一直阻塞下去。
类型互斥量控制着互斥量的特性,POSIX.1定义了四种类型:
(2)读写锁属性
读写锁支持的唯一属性是进程共享属性。它与互斥量的进程共享属性是相同的。
(3)条件变量属性
条件变量支持两种属性:进程共享属性和时钟属性。
进程共享属性控制着条件变量是可以被单进程的多个线程使用,还是可以被多进程的线程使用。
时钟属性控制计算pthread_cond_timedwait函数的超时参数(tsptr)时采用的是哪个时钟。
(4)屏障属性
屏障属性只有进程共享属性。
4、重入
有了信号处理程序和多线程,多个控制线程在同一时间可能潜在的调用同一个函数,如果一个函数在相同的时间点可以被多个线程安全地调用,就称该函数是线程安全的。
很多函数并不是线程安全的,因为它们返回的数据是存放在静态的内存缓冲区,可以通过修改接口,要求调用者自己提供缓冲区使函数变为线程安全的。
5、线程特定数据
线程似有数据时存储和查询与某个线程相关的数据的一种机制,希望每个线程可以独立的访问数据副本,而不需要担心与其他线程的同步访问问题。进程中的所有线程都可以访问进程的整个地址空间,除了使用寄存器以外,线程没有办法阻止其他线程访问它的数据,线程似有数据也不例外。管理线程私有数据的函数可以提高线程间的数据独立性。
分配线程私有数据过程:首先调用pthread_key_create创建与该数据关联的键,用于获取对线程私有数据的访问权,这个键可以被进程中所有线程访问,但是每个线程把这个键与不同的线程私有数据地址进行关联然后通过调用pthread_setspecific函数吧键和线程私有数据关联起来,可以通过pthread_getspecific函数获取线程私有数据的地址。
pthread_key_create函数可以选择为该键关联的析构函数,调用pthread_key_delete函数来取消与线程私有数据值之间的关联关系。通过调用pthread_once函数确保分配的键并不会由于在初始化阶段的竞争而发生变动。
6、线程和信号
每个线程都有自己的信号屏蔽字,但是信号的处理是进程中所有线程共享的。进程中的信号是传递到单个线程的,进程中的信号屏蔽函数sigprocmask函数在线程中没有定义,线程中必须使用pthread_sigmask。线程可以调用sigwait函数等待一个或者多个信发送。调用pthread_kill函数将信号发送到线程。
7、线程和fork
父进程调用fork为子进程创建了整个进程地址空间的副本,子进程从父进程那里继承了所有互斥量、读写锁和条件变量的状态。如果父进程包括多个线程,子进程在fork返回以后,如果紧接着不马上调用exec的话,就需要清理锁。在子进程内部只存在一个线程,它是由父进程中调用fork的线程的副本构成的,父进程中的线程占有锁,则子进程同样占有锁,但是子进程不包含占有锁的线程的副本。通过pthread_atfork函数建立fork处理程序清除锁状态。函数原型如下: int pthread_atfork(void (*prepare)(void), void (*parent)(void),void (*child)(void));
prepare处理程序由父进程在fork创建子进程前调用,获取父进程定义的所有锁。parent处理程序在fork创建子进程以后,但在fork返回之前在父进程环境调用,对prepare处理程序获得的所有锁进行解锁,child处理程序在fork返回之前在子进程环境中调用,也必须释放prepare处理程序获得的所有锁。parent和child处理程序与它们注册时顺序相同,prepare处理程序调用则与注册时的顺序相反。
引用文献:
http://www.cnblogs.com/Anker/archive/2012/12/19/2824990.html